This commit was manufactured by cvs2svn to create tag 'v200709060000'.
diff --git a/assembly/features/org.eclipse.jpt.sdk/.cvsignore b/assembly/features/org.eclipse.jpt.sdk/.cvsignore
deleted file mode 100644
index bc2abf7..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/.cvsignore
+++ /dev/null
@@ -1,4 +0,0 @@
-*.bin.dist.zip
-build.xml
-features
-plugins
diff --git a/assembly/features/org.eclipse.jpt.sdk/.project b/assembly/features/org.eclipse.jpt.sdk/.project
deleted file mode 100644
index 821d453..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.sdk</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/assembly/features/org.eclipse.jpt.sdk/build.properties b/assembly/features/org.eclipse.jpt.sdk/build.properties
deleted file mode 100644
index 7200939..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/build.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-bin.includes = feature.xml,\
-               eclipse_update_120.jpg,\
-               epl-v10.html,\
-               license.html,\
-               feature.properties
diff --git a/assembly/features/org.eclipse.jpt.sdk/eclipse_update_120.jpg b/assembly/features/org.eclipse.jpt.sdk/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/assembly/features/org.eclipse.jpt.sdk/epl-v10.html b/assembly/features/org.eclipse.jpt.sdk/epl-v10.html
deleted file mode 100644
index ed4b196..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
\ No newline at end of file
diff --git a/assembly/features/org.eclipse.jpt.sdk/feature.properties b/assembly/features/org.eclipse.jpt.sdk/feature.properties
deleted file mode 100644
index abb0c88..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/feature.properties
+++ /dev/null
@@ -1,145 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-# feature.properties
-# contains externalized strings for feature.xml
-# "%foo" in feature.xml corresponds to the key "foo" in this file
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file should be translated.
-
-# "featureName" property - name of the feature
-featureName=Dali Java Persistence API (JPA) project SDK
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
-
-# "description" property - description of the feature
-description=Dali Java Persistence API (JPA) project SDK
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-June 06, 2007\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-    - Common Development and Distribution License (CDDL) Version 1.0 (available at http://www.sun.com/cddl/cddl.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/assembly/features/org.eclipse.jpt.sdk/feature.xml b/assembly/features/org.eclipse.jpt.sdk/feature.xml
deleted file mode 100644
index 4b10e05..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/feature.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt.sdk"
-      label="%featureName"
-      version="1.0.0.qualifier"
-      provider-name="%providerName"
-      plugin="org.eclipse.jpt"
-      image="eclipse_update_120.jpg">
-
-   <description>
-      %description
-   </description>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/webtools/updates"/>
-      <discovery label="Web Tools Platform (WTP) Updates" url="http://download.eclipse.org/webtools/updates"/>
-   </url>
-
-   <includes
-         id="org.eclipse.jpt_sdk.feature"
-         version="0.0.0"/>
-
-   <plugin
-         id="org.eclipse.jpt"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/assembly/features/org.eclipse.jpt.sdk/license.html b/assembly/features/org.eclipse.jpt.sdk/license.html
deleted file mode 100644
index 76abfb4..0000000
--- a/assembly/features/org.eclipse.jpt.sdk/license.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
-<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
-<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
-<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
-<BODY lang=EN-US vLink=purple link=blue>
-<H2>Eclipse Foundation Software User Agreement</H2>
-<P>June 06, 2007</P>
-<H3>Usage Of Content</H3>
-<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
-AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
-THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
-TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
-BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
-BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
-AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
-APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
-MAY NOT USE THE CONTENT.</P>
-<H3>Applicable Licenses</H3>
-<P>Unless otherwise indicated, all Content made available by the Eclipse 
-Foundation is provided to you under the terms and conditions of the Eclipse 
-Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
-Content and is also available at <A 
-href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-<P>Content includes, but is not limited to, source code, object code, 
-documentation and other files maintained in the Eclipse.org CVS repository 
-("Repository") in CVS modules ("Modules") and made available as downloadable 
-archives ("Downloads").</P>
-<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
-("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
-Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
-contain a list of the names and version numbers of the Plug-ins and/or Fragments 
-associated with a Feature. Plug-ins and Fragments are located in directories 
-named "plugins" and Features are located in directories named "features".</P>
-<P>Features may also include other Features ("Included Features"). Files named 
-"feature.xml" may contain a list of the names and version numbers of Included 
-Features.</P>
-<P>The terms and conditions governing Plug-ins and Fragments should be contained 
-in files named "about.html" ("Abouts"). The terms and conditions governing 
-Features and Included Features should be contained in files named "license.html" 
-("Feature Licenses"). Abouts and Feature Licenses may be located in any 
-directory of a Download or Module including, but not limited to the following 
-locations:</P>
-<UL>
-  <LI>The top-level (root) directory 
-  <LI>Plug-in and Fragment directories 
-  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
-  <LI>Feature directories </LI></UL>
-<P>Note: if a Feature made available by the Eclipse Foundation is installed 
-using the Eclipse Update Manager, you must agree to a license ("Feature Update 
-License") during the installation process. If the Feature contains Included 
-Features, the Feature Update License should either provide you with the terms 
-and conditions governing the Included Features or inform you where you can 
-locate them. Feature Update Licenses may be found in the "license" property of 
-files named "feature.properties". Such Abouts, Feature Licenses and Feature 
-Update Licenses contain the terms and conditions (or references to such terms 
-and conditions) that govern your use of the associated Content in that 
-directory.</P>
-<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
-OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
-<UL>
-  <LI>Common Public License Version 1.0 (available at <A 
-  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
-
-  <LI>Apache Software License 1.1 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
-
-  <LI>Apache Software License 2.0 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
-
-  <LI>IBM Public License 1.0 (available at <A 
-  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
-
-  <LI>Metro Link Public License 1.00 (available at <A 
-  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
-
-  <LI>Mozilla Public License Version 1.1 (available at <A 
-  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
-  </LI>
-   
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
-provided, please contact the Eclipse Foundation to determine what terms and 
-conditions govern that particular Content.</P>
-<H3>Cryptography</H3>
-<P>Content may contain encryption software. The country in which you are 
-currently may have restrictions on the import, possession, and use, and/or 
-re-export to another country, of encryption software. BEFORE using any 
-encryption software, please check the country's laws, regulations and policies 
-concerning the import, possession, or use, and re-export of encryption software, 
-to see if this is permitted.</P></BODY></HTML>
diff --git a/assembly/features/org.eclipse.jpt.tests/.cvsignore b/assembly/features/org.eclipse.jpt.tests/.cvsignore
deleted file mode 100644
index d9e4340..0000000
--- a/assembly/features/org.eclipse.jpt.tests/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.bin.dist.zip
-build.xml
diff --git a/assembly/features/org.eclipse.jpt.tests/.project b/assembly/features/org.eclipse.jpt.tests/.project
deleted file mode 100644
index 3d1dde6..0000000
--- a/assembly/features/org.eclipse.jpt.tests/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/assembly/features/org.eclipse.jpt.tests/.settings/org.eclipse.core.resources.prefs b/assembly/features/org.eclipse.jpt.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 17acb65..0000000
--- a/assembly/features/org.eclipse.jpt.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:11:05 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/assembly/features/org.eclipse.jpt.tests/build.properties b/assembly/features/org.eclipse.jpt.tests/build.properties
deleted file mode 100644
index 7f47694..0000000
--- a/assembly/features/org.eclipse.jpt.tests/build.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-bin.includes = feature.xml,\
-               eclipse_update_120.jpg,\
-               epl-v10.html,\
-               license.html,\
-               feature.properties
diff --git a/assembly/features/org.eclipse.jpt.tests/eclipse_update_120.jpg b/assembly/features/org.eclipse.jpt.tests/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/assembly/features/org.eclipse.jpt.tests/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/assembly/features/org.eclipse.jpt.tests/epl-v10.html b/assembly/features/org.eclipse.jpt.tests/epl-v10.html
deleted file mode 100644
index ed4b196..0000000
--- a/assembly/features/org.eclipse.jpt.tests/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
\ No newline at end of file
diff --git a/assembly/features/org.eclipse.jpt.tests/feature.properties b/assembly/features/org.eclipse.jpt.tests/feature.properties
deleted file mode 100644
index 6b58fe6..0000000
--- a/assembly/features/org.eclipse.jpt.tests/feature.properties
+++ /dev/null
@@ -1,145 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-# feature.properties
-# contains externalized strings for feature.xml
-# "%foo" in feature.xml corresponds to the key "foo" in this file
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file should be translated.
-
-# "featureName" property - name of the feature
-featureName=Dali Java Persistence API (JPA) project Tests
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
-
-# "description" property - description of the feature
-description=Dali Java Persistence API (JPA) project Tests
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-June 06, 2007\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-    - Common Development and Distribution License (CDDL) Version 1.0 (available at http://www.sun.com/cddl/cddl.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/assembly/features/org.eclipse.jpt.tests/feature.xml b/assembly/features/org.eclipse.jpt.tests/feature.xml
deleted file mode 100644
index e445c4c..0000000
--- a/assembly/features/org.eclipse.jpt.tests/feature.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt.tests"
-      label="%featureName"
-      version="1.0.0.qualifier"
-      provider-name="%providerName">
-
-   <description>
-      %description
-   </description>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/webtools/updates/"/>
-   </url>
-
-   <includes
-         id="org.eclipse.jpt.tests.feature"
-         version="0.0.0"/>
-     
-</feature>
diff --git a/assembly/features/org.eclipse.jpt.tests/license.html b/assembly/features/org.eclipse.jpt.tests/license.html
deleted file mode 100644
index 5644598..0000000
--- a/assembly/features/org.eclipse.jpt.tests/license.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
-<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
-<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
-<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
-<BODY lang=EN-US vLink=purple link=blue>
-<H2>Eclipse Foundation Software User Agreement</H2>
-<P>June 06, 2007</P>
-<H3>Usage Of Content</H3>
-<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
-AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
-THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
-TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
-BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
-BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
-AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
-APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
-MAY NOT USE THE CONTENT.</P>
-<H3>Applicable Licenses</H3>
-<P>Unless otherwise indicated, all Content made available by the Eclipse 
-Foundation is provided to you under the terms and conditions of the Eclipse 
-Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
-Content and is also available at <A 
-href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-<P>Content includes, but is not limited to, source code, object code, 
-documentation and other files maintained in the Eclipse.org CVS repository 
-("Repository") in CVS modules ("Modules") and made available as downloadable 
-archives ("Downloads").</P>
-<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
-("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
-Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
-contain a list of the names and version numbers of the Plug-ins and/or Fragments 
-associated with a Feature. Plug-ins and Fragments are located in directories 
-named "plugins" and Features are located in directories named "features".</P>
-<P>Features may also include other Features ("Included Features"). Files named 
-"feature.xml" may contain a list of the names and version numbers of Included 
-Features.</P>
-<P>The terms and conditions governing Plug-ins and Fragments should be contained 
-in files named "about.html" ("Abouts"). The terms and conditions governing 
-Features and Included Features should be contained in files named "license.html" 
-("Feature Licenses"). Abouts and Feature Licenses may be located in any 
-directory of a Download or Module including, but not limited to the following 
-locations:</P>
-<UL>
-  <LI>The top-level (root) directory 
-  <LI>Plug-in and Fragment directories 
-  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
-  <LI>Feature directories </LI></UL>
-<P>Note: if a Feature made available by the Eclipse Foundation is installed 
-using the Eclipse Update Manager, you must agree to a license ("Feature Update 
-License") during the installation process. If the Feature contains Included 
-Features, the Feature Update License should either provide you with the terms 
-and conditions governing the Included Features or inform you where you can 
-locate them. Feature Update Licenses may be found in the "license" property of 
-files named "feature.properties". Such Abouts, Feature Licenses and Feature 
-Update Licenses contain the terms and conditions (or references to such terms 
-and conditions) that govern your use of the associated Content in that 
-directory.</P>
-<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
-OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
-<UL>
-  <LI>Common Public License Version 1.0 (available at <A 
-  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
-
-  <LI>Apache Software License 1.1 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
-
-  <LI>Apache Software License 2.0 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
-
-  <LI>IBM Public License 1.0 (available at <A 
-  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
-
-  <LI>Metro Link Public License 1.00 (available at <A 
-  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
-
-  <LI>Mozilla Public License Version 1.1 (available at <A 
-  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
-  </LI>
-    
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
-provided, please contact the Eclipse Foundation to determine what terms and 
-conditions govern that particular Content.</P>
-<H3>Cryptography</H3>
-<P>Content may contain encryption software. The country in which you are 
-currently may have restrictions on the import, possession, and use, and/or 
-re-export to another country, of encryption software. BEFORE using any 
-encryption software, please check the country's laws, regulations and policies 
-concerning the import, possession, or use, and re-export of encryption software, 
-to see if this is permitted.</P></BODY></HTML>
diff --git a/assembly/features/org.eclipse.jpt/.cvsignore b/assembly/features/org.eclipse.jpt/.cvsignore
deleted file mode 100644
index d9e4340..0000000
--- a/assembly/features/org.eclipse.jpt/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.bin.dist.zip
-build.xml
diff --git a/assembly/features/org.eclipse.jpt/.project b/assembly/features/org.eclipse.jpt/.project
deleted file mode 100644
index b7aaec2..0000000
--- a/assembly/features/org.eclipse.jpt/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/assembly/features/org.eclipse.jpt/build.properties b/assembly/features/org.eclipse.jpt/build.properties
deleted file mode 100644
index 470b4bc..0000000
--- a/assembly/features/org.eclipse.jpt/build.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-bin.includes = feature.xml,\
-               eclipse_update_120.jpg,\
-               epl-v10.html,\
-               license.html,\
-               feature.properties
-               
\ No newline at end of file
diff --git a/assembly/features/org.eclipse.jpt/eclipse_update_120.jpg b/assembly/features/org.eclipse.jpt/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/assembly/features/org.eclipse.jpt/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/assembly/features/org.eclipse.jpt/epl-v10.html b/assembly/features/org.eclipse.jpt/epl-v10.html
deleted file mode 100644
index ed4b196..0000000
--- a/assembly/features/org.eclipse.jpt/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
\ No newline at end of file
diff --git a/assembly/features/org.eclipse.jpt/feature.properties b/assembly/features/org.eclipse.jpt/feature.properties
deleted file mode 100644
index 0ae42bb..0000000
--- a/assembly/features/org.eclipse.jpt/feature.properties
+++ /dev/null
@@ -1,144 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-# feature.properties
-# contains externalized strings for feature.xml
-# "%foo" in feature.xml corresponds to the key "foo" in this file
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file should be translated.
-
-# "featureName" property - name of the feature
-featureName=Java Persistence API Tools
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
-
-# "description" property - description of the feature
-description=Java Persistence API Tools - Runtime
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-March 17, 2005\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/assembly/features/org.eclipse.jpt/feature.xml b/assembly/features/org.eclipse.jpt/feature.xml
deleted file mode 100644
index fdae561..0000000
--- a/assembly/features/org.eclipse.jpt/feature.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt"
-      label="%featureName"
-      version="1.0.0.qualifier"
-      provider-name="%providerName"
-      plugin="org.eclipse.jpt"
-      image="eclipse_update_120.jpg">
-
-   <description>
-      %description
-   </description>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/webtools/updates"/>
-      <discovery label="Web Tools Platform (WTP) Updates" url="http://download.eclipse.org/webtools/updates"/>
-   </url>
-
-   <includes
-         id="org.eclipse.jpt.feature"
-         version="0.0.0"/>
-
-   <plugin
-         id="org.eclipse.jpt"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/assembly/features/org.eclipse.jpt/license.html b/assembly/features/org.eclipse.jpt/license.html
deleted file mode 100644
index 2347060..0000000
--- a/assembly/features/org.eclipse.jpt/license.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
-<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
-<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
-<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
-<BODY lang=EN-US vLink=purple link=blue>
-<H2>Eclipse Foundation Software User Agreement</H2>
-<P>January 28, 2005</P>
-<H3>Usage Of Content</H3>
-<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
-AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
-THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
-TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
-BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
-BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
-AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
-APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
-MAY NOT USE THE CONTENT.</P>
-<H3>Applicable Licenses</H3>
-<P>Unless otherwise indicated, all Content made available by the Eclipse 
-Foundation is provided to you under the terms and conditions of the Eclipse 
-Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
-Content and is also available at <A 
-href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-<P>Content includes, but is not limited to, source code, object code, 
-documentation and other files maintained in the Eclipse.org CVS repository 
-("Repository") in CVS modules ("Modules") and made available as downloadable 
-archives ("Downloads").</P>
-<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
-("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
-Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
-contain a list of the names and version numbers of the Plug-ins and/or Fragments 
-associated with a Feature. Plug-ins and Fragments are located in directories 
-named "plugins" and Features are located in directories named "features".</P>
-<P>Features may also include other Features ("Included Features"). Files named 
-"feature.xml" may contain a list of the names and version numbers of Included 
-Features.</P>
-<P>The terms and conditions governing Plug-ins and Fragments should be contained 
-in files named "about.html" ("Abouts"). The terms and conditions governing 
-Features and Included Features should be contained in files named "license.html" 
-("Feature Licenses"). Abouts and Feature Licenses may be located in any 
-directory of a Download or Module including, but not limited to the following 
-locations:</P>
-<UL>
-  <LI>The top-level (root) directory 
-  <LI>Plug-in and Fragment directories 
-  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
-  <LI>Feature directories </LI></UL>
-<P>Note: if a Feature made available by the Eclipse Foundation is installed 
-using the Eclipse Update Manager, you must agree to a license ("Feature Update 
-License") during the installation process. If the Feature contains Included 
-Features, the Feature Update License should either provide you with the terms 
-and conditions governing the Included Features or inform you where you can 
-locate them. Feature Update Licenses may be found in the "license" property of 
-files named "feature.properties". Such Abouts, Feature Licenses and Feature 
-Update Licenses contain the terms and conditions (or references to such terms 
-and conditions) that govern your use of the associated Content in that 
-directory.</P>
-<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
-OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
-<UL>
-  <LI>Common Public License Version 1.0 (available at <A 
-  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
-
-  <LI>Apache Software License 1.1 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
-
-  <LI>Apache Software License 2.0 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
-
-  <LI>IBM Public License 1.0 (available at <A 
-  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
-
-  <LI>Metro Link Public License 1.00 (available at <A 
-  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
-
-  <LI>Mozilla Public License Version 1.1 (available at <A 
-  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
-  </LI></UL>
-<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
-provided, please contact the Eclipse Foundation to determine what terms and 
-conditions govern that particular Content.</P>
-<H3>Cryptography</H3>
-<P>Content may contain encryption software. The country in which you are 
-currently may have restrictions on the import, possession, and use, and/or 
-re-export to another country, of encryption software. BEFORE using any 
-encryption software, please check the country's laws, regulations and policies 
-concerning the import, possession, or use, and re-export of encryption software, 
-to see if this is permitted.</P></BODY></HTML>
diff --git a/assembly/plugins/org.eclipse.jpt/.cvsignore b/assembly/plugins/org.eclipse.jpt/.cvsignore
deleted file mode 100644
index e4254b1..0000000
--- a/assembly/plugins/org.eclipse.jpt/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-bin
-temp.folder
-build.xml
diff --git a/assembly/plugins/org.eclipse.jpt/.project b/assembly/plugins/org.eclipse.jpt/.project
deleted file mode 100644
index f51b04c..0000000
--- a/assembly/plugins/org.eclipse.jpt/.project
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-	</natures>
-</projectDescription>
diff --git a/assembly/plugins/org.eclipse.jpt/.settings/org.eclipse.core.resources.prefs b/assembly/plugins/org.eclipse.jpt/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 4aec29d..0000000
--- a/assembly/plugins/org.eclipse.jpt/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:10:09 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/assembly/plugins/org.eclipse.jpt/META-INF/MANIFEST.MF b/assembly/plugins/org.eclipse.jpt/META-INF/MANIFEST.MF
deleted file mode 100644
index 5ac613e..0000000
--- a/assembly/plugins/org.eclipse.jpt/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,7 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.jpt; singleton:=true
-Bundle-Version: 1.0.0.qualifier
-Bundle-Localization: plugin
-Bundle-Vendor: %providerName
diff --git a/assembly/plugins/org.eclipse.jpt/about.html b/assembly/plugins/org.eclipse.jpt/about.html
deleted file mode 100644
index ca606b1..0000000
--- a/assembly/plugins/org.eclipse.jpt/about.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
-
-<head>
-<title>About</title>
-<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
-</head>
-
-<BODY lang="EN-US">
-
-<H3>About This Content</H3>
-
-<P>June 06, 2007</P>
-
-<H3>License</H3>
-
-<P>The Eclipse Foundation makes available all content in this plug-in 
-("Content"). Unless otherwise indicated below, the Content is provided to you 
-under the terms and conditions of the Eclipse Public License Version 1.0 
-("EPL"). A copy of the EPL is available at
-<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-
-<P>If you did not receive this Content directly from the Eclipse Foundation, the 
-Content is being redistributed by another party ("Redistributor") and different 
-terms and conditions may apply to your use of any object code in the Content. 
-Check the Redistributor's license that was provided with the Content. If no such 
-license exists, contact the Redistributor. Unless otherwise indicated below, the 
-terms and conditions of the EPL still apply to any source code in the Content 
-and such source code may be obtained at
-<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P>
-
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/assembly/plugins/org.eclipse.jpt/about.ini b/assembly/plugins/org.eclipse.jpt/about.ini
deleted file mode 100644
index 588a325..0000000
--- a/assembly/plugins/org.eclipse.jpt/about.ini
+++ /dev/null
@@ -1,44 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-
-# about.ini
-# contains information about a feature
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# "%key" are externalized strings defined in about.properties
-# This file does not need to be translated.
-
-# Property "aboutText" contains blurb for "About" dialog (translated)
-aboutText=%blurb
-
-# Property "windowImage" contains path to window icon (16x16)
-# needed for primary features only
-
-# Property "featureImage" contains path to feature image (32x32)
-featureImage=eclipse32.gif
-
-# Property "aboutImage" contains path to product image (500x330 or 115x164)
-# needed for primary features only
-
-# Property "appName" contains name of the application (translated)
-# needed for primary features only
-
-# Property "welcomePage" contains path to welcome page (special XML-based format)
-# optional
-
-# Property "welcomePerspective" contains the id of the perspective in which the
-# welcome page is to be opened.
-# optional
-
-# Property "tipsAndTricksHref" contains the Help topic href to a tips and tricks page 
-# optional
-tipsAndTricksHref=/org.eclipse.jpt.doc.user/tips_and_tricks.htm
-
-
diff --git a/assembly/plugins/org.eclipse.jpt/about.mappings b/assembly/plugins/org.eclipse.jpt/about.mappings
deleted file mode 100644
index bddaab4..0000000
--- a/assembly/plugins/org.eclipse.jpt/about.mappings
+++ /dev/null
@@ -1,6 +0,0 @@
-# about.mappings
-# contains fill-ins for about.properties
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file does not need to be translated.
-
-0=@build@
\ No newline at end of file
diff --git a/assembly/plugins/org.eclipse.jpt/about.properties b/assembly/plugins/org.eclipse.jpt/about.properties
deleted file mode 100644
index 159bfce..0000000
--- a/assembly/plugins/org.eclipse.jpt/about.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-
-# about.properties
-# contains externalized strings for about.ini
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# fill-ins are supplied by about.mappings
-# This file should be translated.
-
-blurb=Java Persistence API Tools\n\
-\n\
-Version: {featureVersion}\n\
-Build id: {0}\n\
-\n\
-(c) Copyright Eclipse contributors and others 2006.  All rights reserved.\n\
-Visit http://www.eclipse.org/webtools
diff --git a/assembly/plugins/org.eclipse.jpt/build.properties b/assembly/plugins/org.eclipse.jpt/build.properties
deleted file mode 100644
index 0ccfb0e..0000000
--- a/assembly/plugins/org.eclipse.jpt/build.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-###############################################################################
-# Copyright (c) 2006, 2007 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-bin.includes = META-INF/,\
-               about.ini,\
-               about.html,\
-               about.mappings,\
-               about.properties,\
-               eclipse32.gif,\
-               eclipse32.png,\
-               plugin.properties,\
-               component.xml
diff --git a/assembly/plugins/org.eclipse.jpt/component.xml b/assembly/plugins/org.eclipse.jpt/component.xml
deleted file mode 100644
index 11f133f..0000000
--- a/assembly/plugins/org.eclipse.jpt/component.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<component  xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.jpt">
-<description url=""></description>
-<component-depends unrestricted="true"></component-depends>
-<plugin id="org.eclipse.jpt" fragment="false"/>
-<plugin id="org.eclipse.jpt.core" fragment="false"/>
-<plugin id="org.eclipse.jpt.db" fragment="false"/>
-<plugin id="org.eclipse.jpt.db.ui" fragment="false"/>
-<plugin id="org.eclipse.jpt.gen" fragment="false"/>
-<plugin id="org.eclipse.jpt.ui" fragment="false"/>
-<plugin id="org.eclipse.jpt.utility" fragment="false"/>
-</component>
\ No newline at end of file
diff --git a/assembly/plugins/org.eclipse.jpt/eclipse32.gif b/assembly/plugins/org.eclipse.jpt/eclipse32.gif
deleted file mode 100644
index e6ad7cc..0000000
--- a/assembly/plugins/org.eclipse.jpt/eclipse32.gif
+++ /dev/null
Binary files differ
diff --git a/assembly/plugins/org.eclipse.jpt/eclipse32.png b/assembly/plugins/org.eclipse.jpt/eclipse32.png
deleted file mode 100644
index 568fac1..0000000
--- a/assembly/plugins/org.eclipse.jpt/eclipse32.png
+++ /dev/null
Binary files differ
diff --git a/assembly/plugins/org.eclipse.jpt/plugin.properties b/assembly/plugins/org.eclipse.jpt/plugin.properties
deleted file mode 100644
index f45a08d..0000000
--- a/assembly/plugins/org.eclipse.jpt/plugin.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-
-pluginName = Java Persistence API Tools
-providerName = Eclipse.org
diff --git a/jpa/features/org.eclipse.jpt.feature/.project b/jpa/features/org.eclipse.jpt.feature/.project
deleted file mode 100644
index c8eb2f0..0000000
--- a/jpa/features/org.eclipse.jpt.feature/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/features/org.eclipse.jpt.feature/.settings/org.eclipse.core.resources.prefs b/jpa/features/org.eclipse.jpt.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index dab5837..0000000
--- a/jpa/features/org.eclipse.jpt.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:10:47 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/jpa/features/org.eclipse.jpt.feature/build.properties b/jpa/features/org.eclipse.jpt.feature/build.properties
deleted file mode 100644
index 7200939..0000000
--- a/jpa/features/org.eclipse.jpt.feature/build.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-bin.includes = feature.xml,\
-               eclipse_update_120.jpg,\
-               epl-v10.html,\
-               license.html,\
-               feature.properties
diff --git a/jpa/features/org.eclipse.jpt.feature/eclipse_update_120.jpg b/jpa/features/org.eclipse.jpt.feature/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/jpa/features/org.eclipse.jpt.feature/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt.feature/epl-v10.html b/jpa/features/org.eclipse.jpt.feature/epl-v10.html
deleted file mode 100644
index ed4b196..0000000
--- a/jpa/features/org.eclipse.jpt.feature/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
\ No newline at end of file
diff --git a/jpa/features/org.eclipse.jpt.feature/feature.properties b/jpa/features/org.eclipse.jpt.feature/feature.properties
deleted file mode 100644
index a2b39f3..0000000
--- a/jpa/features/org.eclipse.jpt.feature/feature.properties
+++ /dev/null
@@ -1,140 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle - initial API and implementation
-###############################################################################
-
-# "featureName" property - name of the feature
-featureName=Java Persistence API Tools
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
-
-# "description" property - description of the feature
-description=Java Persistence API (JPA) Tools
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006-07 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-June 06, 2007\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-    - Common Development and Distribution License (CDDL) Version 1.0 (available at http://www.sun.com/cddl/cddl.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/jpa/features/org.eclipse.jpt.feature/feature.xml b/jpa/features/org.eclipse.jpt.feature/feature.xml
deleted file mode 100644
index a6e8a54..0000000
--- a/jpa/features/org.eclipse.jpt.feature/feature.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt.feature"
-      label="%featureName"
-      version="1.0.0.qualifier"
-      provider-name="%providerName"
-      image="eclipse_update_120.jpg">
-
-   <description>
-      %description
-   </description>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <url>
-      <update label="Web Tools Platform (WTP) Updates" url="http://download.eclipse.org/webtools/updates"/>
-      <discovery label="Web Tools Platform (WTP) Updates" url="http://download.eclipse.org/webtools/updates"/>
-      <discovery label="Dali Java Persistence API Tools (JPA) Updates" url="http://download.eclipse.org/webtools/updates/"/>
-   </url>
-
-   <requires>
-      <import plugin="org.eclipse.core.runtime"/>
-      <import plugin="org.eclipse.ui"/>
-      <import feature="org.eclipse.datatools.connectivity.feature"/>
-      <import feature="org.eclipse.datatools.modelbase.feature"/>
-      <import feature="org.eclipse.datatools.sqldevtools.feature"/>
-      <import feature="org.eclipse.datatools.enablement.feature"/>
-      <import plugin="org.eclipse.datatools.connectivity.db.generic.ui"/>
-      <import plugin="org.eclipse.datatools.connectivity.db.generic"/>  
-      <import plugin="org.eclipse.datatools.doc.user"/>
-      <import plugin="org.eclipse.jdt.core"/>
-      <import plugin="org.eclipse.core.commands"/>
-      <import plugin="org.eclipse.core.expressions"/>
-      <import plugin="org.eclipse.core.filebuffers"/>
-      <import plugin="org.eclipse.core.resources"/>
-      <import plugin="org.eclipse.emf.ecore"/>
-      <import plugin="org.eclipse.emf.ecore.xmi"/>
-      <import plugin="org.eclipse.jem"/>
-      <import plugin="org.eclipse.jem.util"/>
-      <import plugin="org.eclipse.jem.workbench"/>
-      <import plugin="org.eclipse.jst.j2ee"/>
-      <import plugin="org.eclipse.jst.j2ee.core"/>
-      <import plugin="org.eclipse.text"/>
-      <import plugin="org.eclipse.wst.common.emf"/>
-      <import plugin="org.eclipse.wst.common.frameworks"/>
-      <import plugin="org.eclipse.wst.common.modulecore"/>
-      <import plugin="org.eclipse.wst.common.project.facet.core"/>
-      <import plugin="org.eclipse.wst.sse.core"/>
-      <import plugin="org.eclipse.wst.validation"/>
-      <import plugin="org.eclipse.wst.xml.core"/>
-      <import plugin="org.eclipse.xsd"/>
-      <import plugin="org.eclipse.draw2d"/>
-      <import plugin="org.eclipse.emf.edit.ui"/>
-      <import plugin="org.eclipse.jdt.ui"/>
-      <import plugin="org.eclipse.jface.text"/>
-      <import plugin="org.eclipse.jst.j2ee.ui"/>
-      <import plugin="org.eclipse.ui.ide"/>
-      <import plugin="org.eclipse.ui.views.properties.tabbed"/>
-      <import plugin="org.eclipse.ui.workbench.texteditor"/>
-      <import plugin="org.eclipse.wst.common.frameworks.ui"/>
-      <import plugin="org.eclipse.wst.common.project.facet.ui"/>
-      <import plugin="org.eclipse.wst.sse.ui"/>
-      <import plugin="org.eclipse.wst.web.ui"/>
-   </requires>
-
-   <plugin
-         id="org.eclipse.jpt.utility"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.jpt.db"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.jpt.db.ui"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.jpt.gen"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.jpt.core"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.jpt.ui"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
-         id="org.eclipse.jpt.doc.user"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/jpa/features/org.eclipse.jpt.feature/license.html b/jpa/features/org.eclipse.jpt.feature/license.html
deleted file mode 100644
index fc77372..0000000
--- a/jpa/features/org.eclipse.jpt.feature/license.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
-<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
-<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
-<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
-<BODY lang=EN-US vLink=purple link=blue>
-<H2>Eclipse Foundation Software User Agreement</H2>
-<P>June 06, 2007</P>
-<H3>Usage Of Content</H3>
-<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
-AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
-THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
-TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
-BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
-BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
-AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
-APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
-MAY NOT USE THE CONTENT.</P>
-<H3>Applicable Licenses</H3>
-<P>Unless otherwise indicated, all Content made available by the Eclipse 
-Foundation is provided to you under the terms and conditions of the Eclipse 
-Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
-Content and is also available at <A 
-href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-<P>Content includes, but is not limited to, source code, object code, 
-documentation and other files maintained in the Eclipse.org CVS repository 
-("Repository") in CVS modules ("Modules") and made available as downloadable 
-archives ("Downloads").</P>
-<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
-("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
-Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
-contain a list of the names and version numbers of the Plug-ins and/or Fragments 
-associated with a Feature. Plug-ins and Fragments are located in directories 
-named "plugins" and Features are located in directories named "features".</P>
-<P>Features may also include other Features ("Included Features"). Files named 
-"feature.xml" may contain a list of the names and version numbers of Included 
-Features.</P>
-<P>The terms and conditions governing Plug-ins and Fragments should be contained 
-in files named "about.html" ("Abouts"). The terms and conditions governing 
-Features and Included Features should be contained in files named "license.html" 
-("Feature Licenses"). Abouts and Feature Licenses may be located in any 
-directory of a Download or Module including, but not limited to the following 
-locations:</P>
-<UL>
-  <LI>The top-level (root) directory 
-  <LI>Plug-in and Fragment directories 
-  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
-  <LI>Feature directories </LI></UL>
-<P>Note: if a Feature made available by the Eclipse Foundation is installed 
-using the Eclipse Update Manager, you must agree to a license ("Feature Update 
-License") during the installation process. If the Feature contains Included 
-Features, the Feature Update License should either provide you with the terms 
-and conditions governing the Included Features or inform you where you can 
-locate them. Feature Update Licenses may be found in the "license" property of 
-files named "feature.properties". Such Abouts, Feature Licenses and Feature 
-Update Licenses contain the terms and conditions (or references to such terms 
-and conditions) that govern your use of the associated Content in that 
-directory.</P>
-<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
-OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
-<UL>
-  <LI>Common Public License Version 1.0 (available at <A 
-  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
-
-  <LI>Apache Software License 1.1 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
-
-  <LI>Apache Software License 2.0 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
-
-  <LI>IBM Public License 1.0 (available at <A 
-  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
-
-  <LI>Metro Link Public License 1.00 (available at <A 
-  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
-
-  <LI>Mozilla Public License Version 1.1 (available at <A 
-  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
-  </LI>
-  
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
-provided, please contact the Eclipse Foundation to determine what terms and 
-conditions govern that particular Content.</P>
-<H3>Cryptography</H3>
-<P>Content may contain encryption software. The country in which you are 
-currently may have restrictions on the import, possession, and use, and/or 
-re-export to another country, of encryption software. BEFORE using any 
-encryption software, please check the country's laws, regulations and policies 
-concerning the import, possession, or use, and re-export of encryption software, 
-to see if this is permitted.</P></BODY></HTML>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/build.properties b/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/build.properties
deleted file mode 100644
index 997dd3f..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/build.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-###############################################################################
-# Copyright (c) 2006, 2007 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle - initial API and implementation
-###############################################################################
-bin.includes =\
-epl-v10.html,\
-eclipse_update_120.jpg,\
-feature.xml,\
-feature.properties,\
-license.html
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/eclipse_update_120.jpg b/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/epl-v10.html b/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/epl-v10.html
deleted file mode 100644
index 022ad29..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/feature.properties b/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/feature.properties
deleted file mode 100644
index 0c1da15..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/feature.properties
+++ /dev/null
@@ -1,145 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle - initial API and implementation
-###############################################################################
-# feature.properties
-# contains externalized strings for feature.xml
-# "%foo" in feature.xml corresponds to the key "foo" in this file
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file should be translated.
-
-# "featureName" property - name of the feature
-featureName=Dali Java Persistence API (JPA) Tools
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
-
-# "description" property - description of the feature
-description=Dali Java Persistence API (JPA) Tools
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-June 06, 2007\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-    - Common Development and Distribution License (CDDL) Version 1.0 (available at http://www.sun.com/cddl/cddl.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/feature.xml b/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/feature.xml
deleted file mode 100644
index 12e267e..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/feature.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt.feature.source"
-      label="%featureName"
-      version="1.0.0.qualifier"
-      provider-name="%providerName">
-
-   <description>
-      %description
-   </description>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <plugin
-         id="org.eclipse.jpt.feature.source"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"/>
-
-</feature>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/license.html b/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/license.html
deleted file mode 100644
index fec4a48..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplateFeature/license.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<html>
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<title>Eclipse.org Software User Agreement</title>
-</head>
-
-<body lang="EN-US" link=blue vlink=purple>
-<h2>Eclipse Foundation Software User Agreement</h2>
-<p>June 06, 2007</p>
-
-<h3>Usage Of Content</h3>
-
-<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
-   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
-   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
-   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
-   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
-   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
-   
-<h3>Applicable Licenses</h3>   
-   
-<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
-   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository (&quot;Repository&quot;) in CVS
-   modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
-   
-<ul>
-	<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
-	<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
-	<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
-      and/or Fragments associated with that Feature.</li>
-	<li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
-</ul>   
- 
-<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
-Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
-including, but not limited to the following locations:</p>
-
-<ul>
-	<li>The top-level (root) directory</li>
-	<li>Plug-in and Fragment directories</li>
-	<li>Inside Plug-ins and Fragments packaged as JARs</li>
-	<li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
-	<li>Feature directories</li>
-</ul>
-		
-<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license (&quot;Feature Update License&quot;) during the
-installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
-inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
-Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
-that directory.</p>
-
-<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
-
-<ul>
-	<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
-	<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
-	<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
-	<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>	
-	<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
-	<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-
-<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
-contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
-
-<h3>Cryptography</h3>
-
-<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
-   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
-   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
-   
-<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>   
-</body>
-</html>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.html b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.html
deleted file mode 100644
index d4916df..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<html>
-<head>
-<title>About</title>
-<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
-
-<p>June 06, 2007</p>	
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
-apply to your use of any object code in the Content.  Check the Redistributor's license that was provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content.</p>
-
-<h3>Source Code</h3>
-<p>This plug-in contains source code zip files (&quot;Source Zips&quot;) that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
-agreements and/or notices. Details about these license agreements and notices are contained in &quot;about.html&quot; files (&quot;Abouts&quot;) located in sub-directories in the
-src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
-
-</body>
-</html>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.ini b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.ini
deleted file mode 100644
index 2dee36a..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.ini
+++ /dev/null
@@ -1,31 +0,0 @@
-# about.ini
-# contains information about a feature
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# "%key" are externalized strings defined in about.properties
-# This file does not need to be translated.
-
-# Property "aboutText" contains blurb for "About" dialog (translated)
-aboutText=%blurb
-
-# Property "windowImage" contains path to window icon (16x16)
-# needed for primary features only
-
-# Property "featureImage" contains path to feature image (32x32)
-featureImage=eclipse32.gif
-
-# Property "aboutImage" contains path to product image (500x330 or 115x164)
-# needed for primary features only
-
-# Property "appName" contains name of the application (not translated)
-# needed for primary features only
-
-# Property "welcomePage" contains path to welcome page (special XML-based format)
-# optional
-
-# Property "welcomePerspective" contains the id of the perspective in which the
-# welcome page is to be opened.
-# optional
-
-
-
-
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.mappings b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.mappings
deleted file mode 100644
index a28390a..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.mappings
+++ /dev/null
@@ -1,6 +0,0 @@
-# about.mappings
-# contains fill-ins for about.properties
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file does not need to be translated.
-
-0=@build@
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.properties b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.properties
deleted file mode 100644
index 5e52cb2..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/about.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-###############################################################################
-# Copyright (c) 2000, 2005 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-# about.properties
-# contains externalized strings for about.ini
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# fill-ins are supplied by about.mappings
-# This file should be translated.
-#
-# Do not translate any values surrounded by {}
-
-blurb=JavaServer Faces Tooling Source\n\
-\n\
-Version: {featureVersion}\n\
-Build id: {0}\n\
-\n\
-(c) Copyright Eclipse contributors and others 2005.  All rights reserved.\n\
-Visit http://www.eclipse.org/webtools
-
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/build.properties b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/build.properties
deleted file mode 100644
index e3098b3..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/build.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-bin.includes =\
-               about.html,\
-               about.ini,\
-               about.mappings,\
-               about.properties,\
-               eclipse32.gif,\
-               plugin.properties,\
-               plugin.xml,\
-               src/**,\
-               META-INF/
-sourcePlugin = true
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse32.gif b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse32.gif
deleted file mode 100644
index e6ad7cc..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse32.gif
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse32.png b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse32.png
deleted file mode 100644
index 50ae49d..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse32.png
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse_update_120.jpg b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/epl-v10.html b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/epl-v10.html
deleted file mode 100644
index 022ad29..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/license.html b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/license.html
deleted file mode 100644
index 14b1d50..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/license.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<html>
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<title>Eclipse.org Software User Agreement</title>
-</head>
-
-<body lang="EN-US" link=blue vlink=purple>
-<h2>Eclipse Foundation Software User Agreement</h2>
-<p>June 06, 2007</p>
-
-<h3>Usage Of Content</h3>
-
-<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
-   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
-   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
-   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
-   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
-   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
-   
-<h3>Applicable Licenses</h3>   
-   
-<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
-   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository (&quot;Repository&quot;) in CVS
-   modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
-   
-<ul>
-	<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
-	<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
-	<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
-      and/or Fragments associated with that Feature.</li>
-	<li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
-</ul>   
- 
-<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
-Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
-including, but not limited to the following locations:</p>
-
-<ul>
-	<li>The top-level (root) directory</li>
-	<li>Plug-in and Fragment directories</li>
-	<li>Inside Plug-ins and Fragments packaged as JARs</li>
-	<li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
-	<li>Feature directories</li>
-</ul>
-		
-<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license (&quot;Feature Update License&quot;) during the
-installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
-inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
-Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
-that directory.</p>
-
-<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
-
-<ul>
-	<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
-	<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
-	<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
-	<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>	
-	<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
-	<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
-  
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-
-<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
-contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
-
-<h3>Cryptography</h3>
-
-<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
-   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
-   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
-   
-<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>   
-</body>
-</html>
diff --git a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/plugin.properties b/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/plugin.properties
deleted file mode 100644
index 088161f..0000000
--- a/jpa/features/org.eclipse.jpt.feature/sourceTemplatePlugin/plugin.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-
-pluginName = Dali Java Persistence API (JPA) Tools
-providerName = Eclipse.org
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/.project b/jpa/features/org.eclipse.jpt.tests.feature/.project
deleted file mode 100644
index 91760f2..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.tests.feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/.settings/org.eclipse.core.resources.prefs b/jpa/features/org.eclipse.jpt.tests.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 235b84a..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:11:17 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/build.properties b/jpa/features/org.eclipse.jpt.tests.feature/build.properties
deleted file mode 100644
index d6a4dce..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/build.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-bin.includes = feature.xml,\
-               eclipse_update_120.jpg,\
-               epl-v10.html,\
-               license.html,\
-               feature.properties
-src.includes = license.html,\
-               feature.xml,\
-               epl-v10.html,\
-               eclipse_update_120.jpg,\
-               build.properties
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/eclipse_update_120.jpg b/jpa/features/org.eclipse.jpt.tests.feature/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/epl-v10.html b/jpa/features/org.eclipse.jpt.tests.feature/epl-v10.html
deleted file mode 100644
index ed4b196..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
\ No newline at end of file
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/feature.properties b/jpa/features/org.eclipse.jpt.tests.feature/feature.properties
deleted file mode 100644
index 33ec536..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/feature.properties
+++ /dev/null
@@ -1,145 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle - initial API and implementation
-###############################################################################
-# feature.properties
-# contains externalized strings for feature.xml
-# "%foo" in feature.xml corresponds to the key "foo" in this file
-# java.io.Properties file (ISO 8859-1 with "\" escapes)
-# This file should be translated.
-
-# "featureName" property - name of the feature
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-# TOREVIEW - updateSiteName
-updateSiteName=Web Tools Platform (WTP) Updates
-
-# "description" property - description of the feature
-description=Dali Java Persistence API (JPA) Tools
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-June 06, 2007\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-    - Common Development and Distribution License (CDDL) Version 1.0 (available at http://www.sun.com/cddl/cddl.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/feature.xml b/jpa/features/org.eclipse.jpt.tests.feature/feature.xml
deleted file mode 100644
index 2034cac..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/feature.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt.tests.feature"
-      label="Dali Java Persistence API Tools (JPA) JUnit Tests"
-      version="1.0.0.qualifier"
-      provider-name="Eclipse.org">
-
-   <description>
-      %description
-   </description>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <plugin
-         id="org.eclipse.jpt.utility.tests"
-         download-size="0"
-         install-size="0"
-         version="0.0.0" />
-
-   <plugin
-         id="org.eclipse.jpt.core.tests"
-         download-size="0"
-         install-size="0"
-         version="0.0.0" />
-
-</feature>
diff --git a/jpa/features/org.eclipse.jpt.tests.feature/license.html b/jpa/features/org.eclipse.jpt.tests.feature/license.html
deleted file mode 100644
index 5644598..0000000
--- a/jpa/features/org.eclipse.jpt.tests.feature/license.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
-<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
-<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
-<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
-<BODY lang=EN-US vLink=purple link=blue>
-<H2>Eclipse Foundation Software User Agreement</H2>
-<P>June 06, 2007</P>
-<H3>Usage Of Content</H3>
-<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
-AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
-THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
-TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
-BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
-BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
-AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
-APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
-MAY NOT USE THE CONTENT.</P>
-<H3>Applicable Licenses</H3>
-<P>Unless otherwise indicated, all Content made available by the Eclipse 
-Foundation is provided to you under the terms and conditions of the Eclipse 
-Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
-Content and is also available at <A 
-href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-<P>Content includes, but is not limited to, source code, object code, 
-documentation and other files maintained in the Eclipse.org CVS repository 
-("Repository") in CVS modules ("Modules") and made available as downloadable 
-archives ("Downloads").</P>
-<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
-("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
-Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
-contain a list of the names and version numbers of the Plug-ins and/or Fragments 
-associated with a Feature. Plug-ins and Fragments are located in directories 
-named "plugins" and Features are located in directories named "features".</P>
-<P>Features may also include other Features ("Included Features"). Files named 
-"feature.xml" may contain a list of the names and version numbers of Included 
-Features.</P>
-<P>The terms and conditions governing Plug-ins and Fragments should be contained 
-in files named "about.html" ("Abouts"). The terms and conditions governing 
-Features and Included Features should be contained in files named "license.html" 
-("Feature Licenses"). Abouts and Feature Licenses may be located in any 
-directory of a Download or Module including, but not limited to the following 
-locations:</P>
-<UL>
-  <LI>The top-level (root) directory 
-  <LI>Plug-in and Fragment directories 
-  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
-  <LI>Feature directories </LI></UL>
-<P>Note: if a Feature made available by the Eclipse Foundation is installed 
-using the Eclipse Update Manager, you must agree to a license ("Feature Update 
-License") during the installation process. If the Feature contains Included 
-Features, the Feature Update License should either provide you with the terms 
-and conditions governing the Included Features or inform you where you can 
-locate them. Feature Update Licenses may be found in the "license" property of 
-files named "feature.properties". Such Abouts, Feature Licenses and Feature 
-Update Licenses contain the terms and conditions (or references to such terms 
-and conditions) that govern your use of the associated Content in that 
-directory.</P>
-<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
-OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
-<UL>
-  <LI>Common Public License Version 1.0 (available at <A 
-  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
-
-  <LI>Apache Software License 1.1 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
-
-  <LI>Apache Software License 2.0 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
-
-  <LI>IBM Public License 1.0 (available at <A 
-  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
-
-  <LI>Metro Link Public License 1.00 (available at <A 
-  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
-
-  <LI>Mozilla Public License Version 1.1 (available at <A 
-  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
-  </LI>
-    
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
-provided, please contact the Eclipse Foundation to determine what terms and 
-conditions govern that particular Content.</P>
-<H3>Cryptography</H3>
-<P>Content may contain encryption software. The country in which you are 
-currently may have restrictions on the import, possession, and use, and/or 
-re-export to another country, of encryption software. BEFORE using any 
-encryption software, please check the country's laws, regulations and policies 
-concerning the import, possession, or use, and re-export of encryption software, 
-to see if this is permitted.</P></BODY></HTML>
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/.project b/jpa/features/org.eclipse.jpt_sdk.feature/.project
deleted file mode 100644
index 33da750..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt_sdk.feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/.settings/org.eclipse.core.resources.prefs b/jpa/features/org.eclipse.jpt_sdk.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 6cc7d4b..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:09:59 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/build.properties b/jpa/features/org.eclipse.jpt_sdk.feature/build.properties
deleted file mode 100644
index 28724c6..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/build.properties
+++ /dev/null
@@ -1,9 +0,0 @@
-bin.includes = feature.xml,\
-               license.html,\
-               feature.properties,\
-               epl-v10.html,\
-               eclipse_update_120.jpg
-               
-src.includes = build.properties
-
-generate.feature@org.eclipse.jpt.feature.source=org.eclipse.jpt.feature
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/eclipse_update_120.jpg b/jpa/features/org.eclipse.jpt_sdk.feature/eclipse_update_120.jpg
deleted file mode 100644
index bfdf708..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/eclipse_update_120.jpg
+++ /dev/null
Binary files differ
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/epl-v10.html b/jpa/features/org.eclipse.jpt_sdk.feature/epl-v10.html
deleted file mode 100644
index ed4b196..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/epl-v10.html
+++ /dev/null
@@ -1,328 +0,0 @@
-<html xmlns:o="urn:schemas-microsoft-com:office:office"
-xmlns:w="urn:schemas-microsoft-com:office:word"
-xmlns="http://www.w3.org/TR/REC-html40">
-
-<head>
-<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
-<meta name=ProgId content=Word.Document>
-<meta name=Generator content="Microsoft Word 9">
-<meta name=Originator content="Microsoft Word 9">
-<link rel=File-List
-href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
-<title>Eclipse Public License - Version 1.0</title>
-<!--[if gte mso 9]><xml>
- <o:DocumentProperties>
-  <o:Revision>2</o:Revision>
-  <o:TotalTime>3</o:TotalTime>
-  <o:Created>2004-03-05T23:03:00Z</o:Created>
-  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
-  <o:Pages>4</o:Pages>
-  <o:Words>1626</o:Words>
-  <o:Characters>9270</o:Characters>
-   <o:Lines>77</o:Lines>
-  <o:Paragraphs>18</o:Paragraphs>
-  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
-  <o:Version>9.4402</o:Version>
- </o:DocumentProperties>
-</xml><![endif]--><!--[if gte mso 9]><xml>
- <w:WordDocument>
-  <w:TrackRevisions/>
- </w:WordDocument>
-</xml><![endif]-->
-<style>
-<!--
- /* Font Definitions */
-@font-face
-	{font-family:Tahoma;
-	panose-1:2 11 6 4 3 5 4 4 2 4;
-	mso-font-charset:0;
-	mso-generic-font-family:swiss;
-	mso-font-pitch:variable;
-	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
- /* Style Definitions */
-p.MsoNormal, li.MsoNormal, div.MsoNormal
-	{mso-style-parent:"";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p
-	{margin-right:0in;
-	mso-margin-top-alt:auto;
-	mso-margin-bottom-alt:auto;
-	margin-left:0in;
-	mso-pagination:widow-orphan;
-	font-size:12.0pt;
-	font-family:"Times New Roman";
-	mso-fareast-font-family:"Times New Roman";}
-p.BalloonText, li.BalloonText, div.BalloonText
-	{mso-style-name:"Balloon Text";
-	margin:0in;
-	margin-bottom:.0001pt;
-	mso-pagination:widow-orphan;
-	font-size:8.0pt;
-	font-family:Tahoma;
-	mso-fareast-font-family:"Times New Roman";}
-@page Section1
-	{size:8.5in 11.0in;
-	margin:1.0in 1.25in 1.0in 1.25in;
-	mso-header-margin:.5in;
-	mso-footer-margin:.5in;
-	mso-paper-source:0;}
-div.Section1
-	{page:Section1;}
--->
-</style>
-</head>
-
-<body lang=EN-US style='tab-interval:.5in'>
-
-<div class=Section1>
-
-<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
-</p>
-
-<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
-THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
-REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
-OF THIS AGREEMENT.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-in the case of the initial Contributor, the initial code and documentation
-distributed under this Agreement, and<br clear=left>
-b) in the case of each subsequent Contributor:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-changes to the Program, and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-additions to the Program;</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
-such changes and/or additions to the Program originate from and are distributed
-by that particular Contributor. A Contribution 'originates' from a Contributor
-if it was added to the Program by such Contributor itself or anyone acting on
-such Contributor's behalf. Contributions do not include additions to the
-Program which: (i) are separate modules of software distributed in conjunction
-with the Program under their own license agreement, and (ii) are not derivative
-works of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
-entity that distributes the Program.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
-claims licensable by a Contributor which are necessarily infringed by the use
-or sale of its Contribution alone or when combined with the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
-distributed in accordance with this Agreement.</span> </p>
-
-<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
-receives the Program under this Agreement, including all Contributors.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-Subject to the terms of this Agreement, each Contributor hereby grants Recipient
-a non-exclusive, worldwide, royalty-free copyright license to<span
-style='color:red'> </span>reproduce, prepare derivative works of, publicly
-display, publicly perform, distribute and sublicense the Contribution of such
-Contributor, if any, and such derivative works, in source code and object code
-form.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-Subject to the terms of this Agreement, each Contributor hereby grants
-Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
-patent license under Licensed Patents to make, use, sell, offer to sell, import
-and otherwise transfer the Contribution of such Contributor, if any, in source
-code and object code form. This patent license shall apply to the combination
-of the Contribution and the Program if, at the time the Contribution is added
-by the Contributor, such addition of the Contribution causes such combination
-to be covered by the Licensed Patents. The patent license shall not apply to
-any other combinations which include the Contribution. No hardware per se is
-licensed hereunder. </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
-Recipient understands that although each Contributor grants the licenses to its
-Contributions set forth herein, no assurances are provided by any Contributor
-that the Program does not infringe the patent or other intellectual property
-rights of any other entity. Each Contributor disclaims any liability to Recipient
-for claims brought by any other entity based on infringement of intellectual
-property rights or otherwise. As a condition to exercising the rights and
-licenses granted hereunder, each Recipient hereby assumes sole responsibility
-to secure any other intellectual property rights needed, if any. For example,
-if a third party patent license is required to allow Recipient to distribute
-the Program, it is Recipient's responsibility to acquire that license before
-distributing the Program.</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
-Each Contributor represents that to its knowledge it has sufficient copyright
-rights in its Contribution, if any, to grant the copyright license set forth in
-this Agreement. </span></p>
-
-<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
-
-<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
-Program in object code form under its own license agreement, provided that:</span>
-</p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it complies with the terms and conditions of this Agreement; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
-its license agreement:</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
-effectively disclaims on behalf of all Contributors all warranties and
-conditions, express and implied, including warranties or conditions of title
-and non-infringement, and implied warranties or conditions of merchantability
-and fitness for a particular purpose; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
-effectively excludes on behalf of all Contributors all liability for damages,
-including direct, indirect, special, incidental and consequential damages, such
-as lost profits; </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
-states that any provisions which differ from this Agreement are offered by that
-Contributor alone and not by any other party; and</span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
-states that source code for the Program is available from such Contributor, and
-informs licensees how to obtain it in a reasonable manner on or through a
-medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
-
-<p><span style='font-size:10.0pt'>When the Program is made available in source
-code form:</span> </p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
-it must be made available under this Agreement; and </span></p>
-
-<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
-copy of this Agreement must be included with each copy of the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
-copyright notices contained within the Program. </span></p>
-
-<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
-originator of its Contribution, if any, in a manner that reasonably allows
-subsequent Recipients to identify the originator of the Contribution. </span></p>
-
-<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
-
-<p><span style='font-size:10.0pt'>Commercial distributors of software may
-accept certain responsibilities with respect to end users, business partners
-and the like. While this license is intended to facilitate the commercial use
-of the Program, the Contributor who includes the Program in a commercial
-product offering should do so in a manner which does not create potential
-liability for other Contributors. Therefore, if a Contributor includes the
-Program in a commercial product offering, such Contributor (&quot;Commercial
-Contributor&quot;) hereby agrees to defend and indemnify every other
-Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
-costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
-legal actions brought by a third party against the Indemnified Contributor to
-the extent caused by the acts or omissions of such Commercial Contributor in
-connection with its distribution of the Program in a commercial product
-offering. The obligations in this section do not apply to any claims or Losses
-relating to any actual or alleged intellectual property infringement. In order
-to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
-Contributor in writing of such claim, and b) allow the Commercial Contributor
-to control, and cooperate with the Commercial Contributor in, the defense and
-any related settlement negotiations. The Indemnified Contributor may participate
-in any such claim at its own expense.</span> </p>
-
-<p><span style='font-size:10.0pt'>For example, a Contributor might include the
-Program in a commercial product offering, Product X. That Contributor is then a
-Commercial Contributor. If that Commercial Contributor then makes performance
-claims, or offers warranties related to Product X, those performance claims and
-warranties are such Commercial Contributor's responsibility alone. Under this
-section, the Commercial Contributor would have to defend claims against the
-other Contributors related to those performance claims and warranties, and if a
-court requires any other Contributor to pay any damages as a result, the
-Commercial Contributor must pay those damages.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
-responsible for determining the appropriateness of using and distributing the
-Program and assumes all risks associated with its exercise of rights under this
-Agreement , including but not limited to the risks and costs of program errors,
-compliance with applicable laws, damage to or loss of data, programs or
-equipment, and unavailability or interruption of operations. </span></p>
-
-<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
-
-<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
-AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
-THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
-THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
-
-<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
-
-<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
-or unenforceable under applicable law, it shall not affect the validity or
-enforceability of the remainder of the terms of this Agreement, and without
-further action by the parties hereto, such provision shall be reformed to the
-minimum extent necessary to make such provision valid and enforceable.</span> </p>
-
-<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
-against any entity (including a cross-claim or counterclaim in a lawsuit)
-alleging that the Program itself (excluding combinations of the Program with
-other software or hardware) infringes such Recipient's patent(s), then such
-Recipient's rights granted under Section 2(b) shall terminate as of the date
-such litigation is filed. </span></p>
-
-<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
-shall terminate if it fails to comply with any of the material terms or
-conditions of this Agreement and does not cure such failure in a reasonable
-period of time after becoming aware of such noncompliance. If all Recipient's
-rights under this Agreement terminate, Recipient agrees to cease use and
-distribution of the Program as soon as reasonably practicable. However,
-Recipient's obligations under this Agreement and any licenses granted by
-Recipient relating to the Program shall continue and survive. </span></p>
-
-<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
-copies of this Agreement, but in order to avoid inconsistency the Agreement is
-copyrighted and may only be modified in the following manner. The Agreement
-Steward reserves the right to publish new versions (including revisions) of
-this Agreement from time to time. No one other than the Agreement Steward has
-the right to modify this Agreement. The Eclipse Foundation is the initial
-Agreement Steward. The Eclipse Foundation may assign the responsibility to
-serve as the Agreement Steward to a suitable separate entity. Each new version
-of the Agreement will be given a distinguishing version number. The Program
-(including Contributions) may always be distributed subject to the version of
-the Agreement under which it was received. In addition, after a new version of
-the Agreement is published, Contributor may elect to distribute the Program
-(including its Contributions) under the new version. Except as expressly stated
-in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
-the intellectual property of any Contributor under this Agreement, whether
-expressly, by implication, estoppel or otherwise. All rights in the Program not
-expressly granted under this Agreement are reserved.</span> </p>
-
-<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
-State of New York and the intellectual property laws of the United States of
-America. No party to this Agreement will bring a legal action under this
-Agreement more than one year after the cause of action arose. Each party waives
-its rights to a jury trial in any resulting litigation.</span> </p>
-
-<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
-
-</div>
-
-</body>
-
-</html>
\ No newline at end of file
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/feature.properties b/jpa/features/org.eclipse.jpt_sdk.feature/feature.properties
deleted file mode 100644
index a14204a..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/feature.properties
+++ /dev/null
@@ -1,140 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-
-# "featureName" property - name of the feature
-featureName=Java Persistence API Tools Plug-in SDK
-
-# "providerName" property - name of the company that provides the feature
-providerName=Eclipse.org
-
-# "updateSiteName" property - label for the update site
-updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
-
-# "description" property - description of the feature
-description=Source code zips for JPA Tools
-
-# "copyright" property - text of the "Feature Update Copyright"
-copyright=\
-Copyright (c) 2006-07 Oracle Corporation.\n\
-All rights reserved. This program and the accompanying materials\n\
-are made available under the terms of the Eclipse Public License v1.0\n\
-which accompanies this distribution, and is available at\n\
-http://www.eclipse.org/legal/epl-v10.html\n\
-\n\
-Contributors:\n\
-    Oracle - initial API and implementation\n
-################ end of copyright property ####################################
-
-# "licenseURL" property - URL of the "Feature License"
-# do not translate value - just change to point to a locale-specific HTML page
-licenseURL=license.html
-
-# "license" property - text of the "Feature Update License"
-# should be plain text version of license agreement pointed to be "licenseURL"
-license=\
-ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
-June 06, 2007\n\
-\n\
-Usage Of Content\n\
-\n\
-THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
-OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
-USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
-AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
-NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
-AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
-AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
-OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
-OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
-BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
-\n\
-Applicable Licenses\n\
-\n\
-Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
-is provided to you under the terms and conditions of the Eclipse Public\n\
-License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
-Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
-For purposes of the EPL, "Program" will mean the Content.\n\
-\n\
-Content includes, but is not limited to, source code, object code,\n\
-documentation and other files maintained in the Eclipse.org CVS\n\
-repository ("Repository") in CVS modules ("Modules") and made available\n\
-as downloadable archives ("Downloads").\n\
-\n\
-   - Content may be structured and packaged into modules to facilitate delivering,\n\
-     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
-     plug-in fragments ("Fragments"), and features ("Features").\n\
-   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
-     in a directory named "plugins".\n\
-   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
-     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
-     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
-     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
-   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
-     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
-\n\
-Features may also include other Features ("Included Features"). Files named\n\
-"feature.xml" may contain a list of the names and version numbers of\n\
-Included Features.\n\
-\n\
-The terms and conditions governing Plug-ins and Fragments should be\n\
-contained in files named "about.html" ("Abouts"). The terms and\n\
-conditions governing Features and Included Features should be contained\n\
-in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
-Licenses may be located in any directory of a Download or Module\n\
-including, but not limited to the following locations:\n\
-\n\
-   - The top-level (root) directory\n\
-   - Plug-in and Fragment directories\n\
-   - Inside Plug-ins and Fragments packaged as JARs\n\
-   - Sub-directories of the directory named "src" of certain Plug-ins\n\
-   - Feature directories\n\
-\n\
-Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
-Eclipse Update Manager, you must agree to a license ("Feature Update\n\
-License") during the installation process. If the Feature contains\n\
-Included Features, the Feature Update License should either provide you\n\
-with the terms and conditions governing the Included Features or inform\n\
-you where you can locate them. Feature Update Licenses may be found in\n\
-the "license" property of files named "feature.properties". Such Abouts,\n\
-Feature Licenses and Feature Update Licenses contain the terms and\n\
-conditions (or references to such terms and conditions) that govern your\n\
-use of the associated Content in that directory.\n\
-\n\
-THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
-TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
-SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
-\n\
-    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
-    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
-    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
-    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
-    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
-    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
-    - Common Development and Distribution License (CDDL) Version 1.0 (available at http://www.sun.com/cddl/cddl.html)\n\
-\n\
-IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
-is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
-govern that particular Content.\n\
-\n\
-Cryptography\n\
-\n\
-Content may contain encryption software. The country in which you are\n\
-currently may have restrictions on the import, possession, and use,\n\
-and/or re-export to another country, of encryption software. BEFORE\n\
-using any encryption software, please check the country's laws,\n\
-regulations and policies concerning the import, possession, or use,\n\
-and re-export of encryption software, to see if this is permitted.\n\
-\n\
-Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
-########### end of license property ##########################################
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/feature.xml b/jpa/features/org.eclipse.jpt_sdk.feature/feature.xml
deleted file mode 100644
index 78f3de1..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/feature.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.eclipse.jpt_sdk.feature"
-      label="%featureName"
-      version="1.0.0.qualifier"
-      provider-name="%providerName">
-
-   <description>
-      %description
-   </description>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <license url="license.html">
-      %license
-   </license>
-
-   <includes
-         id="org.eclipse.jpt.feature"
-         version="0.0.0"/>
-
-   <includes
-         id="org.eclipse.jpt.feature.source"
-         version="0.0.0"/>
-
-</feature>
diff --git a/jpa/features/org.eclipse.jpt_sdk.feature/license.html b/jpa/features/org.eclipse.jpt_sdk.feature/license.html
deleted file mode 100644
index fc77372..0000000
--- a/jpa/features/org.eclipse.jpt_sdk.feature/license.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
-<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
-<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
-<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
-<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
-<BODY lang=EN-US vLink=purple link=blue>
-<H2>Eclipse Foundation Software User Agreement</H2>
-<P>June 06, 2007</P>
-<H3>Usage Of Content</H3>
-<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
-AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
-THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
-TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
-BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
-BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
-AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
-TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
-APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
-MAY NOT USE THE CONTENT.</P>
-<H3>Applicable Licenses</H3>
-<P>Unless otherwise indicated, all Content made available by the Eclipse 
-Foundation is provided to you under the terms and conditions of the Eclipse 
-Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
-Content and is also available at <A 
-href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-<P>Content includes, but is not limited to, source code, object code, 
-documentation and other files maintained in the Eclipse.org CVS repository 
-("Repository") in CVS modules ("Modules") and made available as downloadable 
-archives ("Downloads").</P>
-<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
-("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
-Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
-contain a list of the names and version numbers of the Plug-ins and/or Fragments 
-associated with a Feature. Plug-ins and Fragments are located in directories 
-named "plugins" and Features are located in directories named "features".</P>
-<P>Features may also include other Features ("Included Features"). Files named 
-"feature.xml" may contain a list of the names and version numbers of Included 
-Features.</P>
-<P>The terms and conditions governing Plug-ins and Fragments should be contained 
-in files named "about.html" ("Abouts"). The terms and conditions governing 
-Features and Included Features should be contained in files named "license.html" 
-("Feature Licenses"). Abouts and Feature Licenses may be located in any 
-directory of a Download or Module including, but not limited to the following 
-locations:</P>
-<UL>
-  <LI>The top-level (root) directory 
-  <LI>Plug-in and Fragment directories 
-  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
-  <LI>Feature directories </LI></UL>
-<P>Note: if a Feature made available by the Eclipse Foundation is installed 
-using the Eclipse Update Manager, you must agree to a license ("Feature Update 
-License") during the installation process. If the Feature contains Included 
-Features, the Feature Update License should either provide you with the terms 
-and conditions governing the Included Features or inform you where you can 
-locate them. Feature Update Licenses may be found in the "license" property of 
-files named "feature.properties". Such Abouts, Feature Licenses and Feature 
-Update Licenses contain the terms and conditions (or references to such terms 
-and conditions) that govern your use of the associated Content in that 
-directory.</P>
-<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
-OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
-OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
-<UL>
-  <LI>Common Public License Version 1.0 (available at <A 
-  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
-
-  <LI>Apache Software License 1.1 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
-
-  <LI>Apache Software License 2.0 (available at <A 
-  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
-
-  <LI>IBM Public License 1.0 (available at <A 
-  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
-
-  <LI>Metro Link Public License 1.00 (available at <A 
-  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
-
-  <LI>Mozilla Public License Version 1.1 (available at <A 
-  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
-  </LI>
-  
-  <LI>Common Development and Distribution License (CDDL) Version 1.0 (available at <A 
-  href="http://www.sun.com/cddl/cddl.html">http://www.sun.com/cddl/cddl.html)</A>
-  </LI>
-</UL>
-<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
-TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
-provided, please contact the Eclipse Foundation to determine what terms and 
-conditions govern that particular Content.</P>
-<H3>Cryptography</H3>
-<P>Content may contain encryption software. The country in which you are 
-currently may have restrictions on the import, possession, and use, and/or 
-re-export to another country, of encryption software. BEFORE using any 
-encryption software, please check the country's laws, regulations and policies 
-concerning the import, possession, or use, and re-export of encryption software, 
-to see if this is permitted.</P></BODY></HTML>
diff --git a/jpa/plugins/org.eclipse.jpt.core/model/jptResourceModels.genmodel b/jpa/plugins/org.eclipse.jpt.core/model/jptResourceModels.genmodel
new file mode 100644
index 0000000..cd94528
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/model/jptResourceModels.genmodel
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.jpt.core/src"
+    creationCommands="false" creationIcons="false" editDirectory="" editorDirectory=""
+    modelPluginID="org.eclipse.jpt.core" modelName="Core" editPluginClass="" editorPluginClass=""
+    suppressInterfaces="true" testsDirectory="" testSuiteClass="" importerID="org.eclipse.emf.importer.ecore"
+    complianceLevel="5.0" copyrightFields="false" usedGenPackages="platform:/plugin/org.eclipse.emf.ecore/model/Ecore.genmodel#//ecore">
+  <foreignModel>persistence.ecore</foreignModel>
+  <genPackages prefix="Persistence" basePackage="org.eclipse.jpt.core.internal.resource"
+      disposableProviderFactory="true" ecorePackage="persistence.ecore#/">
+    <genEnums typeSafeEnumCompatible="false" ecoreEnum="persistence.ecore#//PersistenceUnitTransactionType">
+      <genEnumLiterals ecoreEnumLiteral="persistence.ecore#//PersistenceUnitTransactionType/JTA"/>
+      <genEnumLiterals ecoreEnumLiteral="persistence.ecore#//PersistenceUnitTransactionType/RESOURCE_LOCAL"/>
+    </genEnums>
+    <genDataTypes ecoreDataType="persistence.ecore#//PersistenceUnitTransactionTypeObject"/>
+    <genDataTypes ecoreDataType="persistence.ecore#//Version"/>
+    <genClasses ecoreClass="persistence.ecore#//Persistence">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference persistence.ecore#//Persistence/persistenceUnits"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//Persistence/version"/>
+    </genClasses>
+    <genClasses ecoreClass="persistence.ecore#//PersistenceUnit">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/description"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/provider"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/jtaDataSource"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/nonJtaDataSource"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference persistence.ecore#//PersistenceUnit/mappingFiles"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/jarFiles"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference persistence.ecore#//PersistenceUnit/classes"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/excludeUnlistedClasses"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference persistence.ecore#//PersistenceUnit/properties"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/name"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//PersistenceUnit/transactionType"/>
+    </genClasses>
+    <genClasses ecoreClass="persistence.ecore#//MappingFileRef">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//MappingFileRef/fileName"/>
+    </genClasses>
+    <genClasses ecoreClass="persistence.ecore#//JavaClassRef">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//JavaClassRef/javaClass"/>
+    </genClasses>
+    <genClasses ecoreClass="persistence.ecore#//Properties">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference persistence.ecore#//Properties/properties"/>
+    </genClasses>
+    <genClasses ecoreClass="persistence.ecore#//Property">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//Property/name"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute persistence.ecore#//Property/value"/>
+    </genClasses>
+  </genPackages>
+</genmodel:GenModel>
diff --git a/jpa/plugins/org.eclipse.jpt.core/model/old_core.ecore b/jpa/plugins/org.eclipse.jpt.core/model/old_core.ecore
new file mode 100644
index 0000000..9f78292
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/model/old_core.ecore
@@ -0,0 +1,588 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="internal"
+    nsURI="jpt.core.xmi" nsPrefix="jpt.core">
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaModel" abstract="true" interface="true"/>
+  <eClassifiers xsi:type="ecore:EClass" name="JpaModel" eSuperTypes="#//JpaEObject #//IJpaModel">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="projects" upperBound="-1"
+        eType="#//IJpaProject" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaEObject" abstract="true" interface="true">
+    <eOperations name="getJpaProject" eType="#//IJpaProject"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JpaEObject" abstract="true" eSuperTypes="#//IJpaEObject"/>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaProject" abstract="true" interface="true"
+      eSuperTypes="#//IJpaEObject">
+    <eOperations name="getModel" lowerBound="1" eType="#//IJpaModel"/>
+    <eOperations name="getPlatform" ordered="false" unique="false" lowerBound="1"
+        eType="#//IJpaPlatform"/>
+    <eOperations name="setPlatform">
+      <eParameters name="platformId" ordered="false" lowerBound="1" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eOperations>
+    <eOperations name="getDataSource" lowerBound="1" eType="#//IJpaDataSource"/>
+    <eOperations name="setDataSource" ordered="false" unique="false" lowerBound="1">
+      <eParameters name="connectionProfileName" ordered="false" unique="false" lowerBound="1"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eOperations>
+    <eOperations name="isDiscoverAnnotatedClasses" lowerBound="1" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+    <eOperations name="setDiscoverAnnotatedClasses" ordered="false" unique="false"
+        lowerBound="1">
+      <eParameters name="discoverAnnotatedClasses" ordered="false" unique="false"
+          lowerBound="1" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+    </eOperations>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JpaProject" eSuperTypes="#//JpaEObject #//IJpaProject">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="platform" ordered="false"
+        unique="false" lowerBound="1" eType="#//IJpaPlatform" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="dataSource" ordered="false"
+        unique="false" eType="#//IJpaDataSource" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="discoverAnnotatedClasses"
+        ordered="false" unique="false" lowerBound="1" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"
+        defaultValueLiteral="false" unsettable="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="files" upperBound="-1"
+        eType="#//IJpaFile" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaPlatform" abstract="true" interface="true"/>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaDataSource" abstract="true" interface="true"
+      eSuperTypes="#//IJpaEObject">
+    <eOperations name="getConnectionProfileName" ordered="false" unique="false" lowerBound="1"
+        eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JpaDataSource" eSuperTypes="#//JpaEObject #//IJpaDataSource">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="connectionProfileName"
+        ordered="false" unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaFile" abstract="true" interface="true"
+      eSuperTypes="#//IJpaEObject">
+    <eOperations name="getContentId" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eOperations name="getContent" eType="#//IJpaRootContentNode"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JpaFile" eSuperTypes="#//JpaEObject #//IJpaFile">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="contentId" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="content" eType="#//IJpaRootContentNode"
+        containment="true" eOpposite="#//IJpaRootContentNode/jpaFile"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaSourceObject" abstract="true" interface="true"
+      eSuperTypes="#//IJpaEObject">
+    <eOperations name="getJpaFile" eType="#//IJpaFile"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IXmlEObject" abstract="true" interface="true"
+      eSuperTypes="#//IJpaEObject #//IJpaSourceObject"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEObject" abstract="true" eSuperTypes="#//JpaEObject #//IXmlEObject"/>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaContentNode" abstract="true" interface="true"
+      eSuperTypes="#//IJpaSourceObject">
+    <eOperations name="getJpaFile" lowerBound="1" eType="#//IJpaFile"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IJpaRootContentNode" abstract="true"
+      interface="true" eSuperTypes="#//IJpaContentNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="jpaFile" eType="#//IJpaFile"
+        changeable="false" eOpposite="#//JpaFile/content"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IPersistentType" abstract="true" interface="true"
+      eSuperTypes="#//IJpaContentNode">
+    <eOperations name="getMapping" lowerBound="1" eType="#//ITypeMapping"/>
+    <eOperations name="parentPersistentType" eType="#//IPersistentType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="mappingKey" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ITypeMapping" abstract="true" interface="true"
+      eSuperTypes="#//IJpaSourceObject">
+    <eOperations name="getPersistentType" lowerBound="1" eType="#//IPersistentType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        changeable="false" volatile="true" derived="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="tableName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        changeable="false" volatile="true" derived="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="NullTypeMapping" eSuperTypes="#//JpaEObject #//ITypeMapping #//IJpaSourceObject"/>
+  <eClassifiers xsi:type="ecore:EClass" name="IPersistentAttribute" abstract="true"
+      interface="true" eSuperTypes="#//IJpaContentNode">
+    <eOperations name="typeMapping" lowerBound="1" eType="#//ITypeMapping"/>
+    <eOperations name="getName" lowerBound="1" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    <eOperations name="mappingKey" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eOperations name="defaultMappingKey" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="mapping" lowerBound="1"
+        eType="#//IAttributeMapping" changeable="false" volatile="true" transient="true"
+        derived="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IAttributeMapping" abstract="true" interface="true"
+      eSuperTypes="#//IJpaSourceObject">
+    <eOperations name="getPersistentAttribute" lowerBound="1" eType="#//IPersistentAttribute"/>
+    <eOperations name="isDefault" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="AccessType">
+    <eLiterals name="Default" literal="Default"/>
+    <eLiterals name="PROPERTY" value="1" literal="Property"/>
+    <eLiterals name="FIELD" value="2" literal="Field"/>
+  </eClassifiers>
+  <eSubpackages name="mappings" nsURI="jpt.core.mappings.xmi" nsPrefix="jpt.core.mappings">
+    <eClassifiers xsi:type="ecore:EClass" name="IMappedSuperclass" abstract="true"
+        interface="true" eSuperTypes="#//ITypeMapping">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="idClass" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IEntity" abstract="true" interface="true"
+        eSuperTypes="#//ITypeMapping">
+      <eOperations name="discriminatorValueIsAllowed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+      <eOperations name="getSecondaryTables" upperBound="-1" eType="#//mappings/ISecondaryTable"/>
+      <eOperations name="parentEntity" eType="#//mappings/IEntity"/>
+      <eOperations name="rootEntity" eType="#//mappings/IEntity"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="table" lowerBound="1"
+          eType="#//mappings/ITable" changeable="false" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedSecondaryTables"
+          upperBound="-1" eType="#//mappings/ISecondaryTable" containment="true" resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="primaryKeyJoinColumns"
+          upperBound="-1" eType="#//mappings/IPrimaryKeyJoinColumn" changeable="false"
+          volatile="true" transient="true" containment="true" resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedPrimaryKeyJoinColumns"
+          upperBound="-1" eType="#//mappings/IPrimaryKeyJoinColumn" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultPrimaryKeyJoinColumns"
+          upperBound="-1" eType="#//mappings/IPrimaryKeyJoinColumn" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="inheritanceStrategy"
+          eType="#//mappings/InheritanceType"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultDiscriminatorValue"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedDiscriminatorValue"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="discriminatorValue" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"
+          changeable="false" volatile="true" transient="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="discriminatorColumn"
+          eType="#//mappings/IDiscriminatorColumn" changeable="false" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="sequenceGenerator" eType="#//mappings/ISequenceGenerator"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="tableGenerator" eType="#//mappings/ITableGenerator"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="attributeOverrides" upperBound="-1"
+          eType="#//mappings/IAttributeOverride" changeable="false" volatile="true"
+          transient="true" containment="true" resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedAttributeOverrides"
+          upperBound="-1" eType="#//mappings/IAttributeOverride" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultAttributeOverrides"
+          upperBound="-1" eType="#//mappings/IAttributeOverride" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associationOverrides"
+          upperBound="-1" eType="#//mappings/IAssociationOverride" changeable="false"
+          volatile="true" transient="true" containment="true" resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedAssociationOverrides"
+          upperBound="-1" eType="#//mappings/IAssociationOverride" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultAssociationOverrides"
+          upperBound="-1" eType="#//mappings/IAssociationOverride" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="namedQueries" upperBound="-1"
+          eType="#//mappings/INamedQuery" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="namedNativeQueries" upperBound="-1"
+          eType="#//mappings/INamedNativeQuery" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="idClass" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IEmbeddable" abstract="true" interface="true"
+        eSuperTypes="#//ITypeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ITable" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="catalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedCatalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultCatalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="schema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedSchema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultSchema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="uniqueConstraints" upperBound="-1"
+          eType="#//mappings/IUniqueConstraint" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IUniqueConstraint" abstract="true"
+        interface="true" eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="columnNames" unique="false"
+          upperBound="-1" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="INamedColumn" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="columnDefinition" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IAbstractColumn" abstract="true" interface="true"
+        eSuperTypes="#//mappings/INamedColumn">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="unique" eType="#//mappings/DefaultFalseBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="nullable" eType="#//mappings/DefaultTrueBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="insertable" eType="#//mappings/DefaultTrueBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="updatable" eType="#//mappings/DefaultTrueBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="table" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedTable" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultTable" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IColumn" abstract="true" interface="true"
+        eSuperTypes="#//mappings/IAbstractColumn">
+      <eOperations name="getDefaultLength" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"/>
+      <eOperations name="getDefaultPrecision" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"/>
+      <eOperations name="getDefaultScale" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="length" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedLength" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="-1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="precision" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedPrecision" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="-1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="scale" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedScale" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="-1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IColumnMapping" abstract="true" interface="true">
+      <eOperations name="getColumn" eType="#//mappings/IColumn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IBasic" abstract="true" interface="true"
+        eSuperTypes="#//IAttributeMapping #//mappings/IColumnMapping">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fetch" eType="#//mappings/DefaultEagerFetchType"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="optional" eType="#//mappings/DefaultTrueBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="column" lowerBound="1"
+          eType="#//mappings/IColumn" changeable="false" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="lob" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="temporal" eType="#//mappings/TemporalType"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="enumerated" eType="#//mappings/EnumType"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IId" abstract="true" interface="true"
+        eSuperTypes="#//IAttributeMapping #//mappings/IColumnMapping">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="column" lowerBound="1"
+          eType="#//mappings/IColumn" changeable="false" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedValue" eType="#//mappings/IGeneratedValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="temporal" eType="#//mappings/TemporalType"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="tableGenerator" eType="#//mappings/ITableGenerator"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="sequenceGenerator" eType="#//mappings/ISequenceGenerator"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ITransient" abstract="true" interface="true"
+        eSuperTypes="#//IAttributeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IVersion" abstract="true" interface="true"
+        eSuperTypes="#//IAttributeMapping #//mappings/IColumnMapping">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="column" lowerBound="1"
+          eType="#//mappings/IColumn" changeable="false" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="temporal" eType="#//mappings/TemporalType"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IEmbeddedId" abstract="true" interface="true"
+        eSuperTypes="#//IAttributeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IEmbedded" abstract="true" interface="true"
+        eSuperTypes="#//IAttributeMapping">
+      <eOperations name="embeddable" eType="#//mappings/IEmbeddable"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="attributeOverrides" upperBound="-1"
+          eType="#//mappings/IAttributeOverride" changeable="false" volatile="true"
+          transient="true" containment="true" resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedAttributeOverrides"
+          upperBound="-1" eType="#//mappings/IAttributeOverride" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultAttributeOverrides"
+          upperBound="-1" eType="#//mappings/IAttributeOverride" containment="true"
+          resolveProxies="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IRelationshipMapping" abstract="true"
+        interface="true" eSuperTypes="#//IAttributeMapping">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="targetEntity" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedTargetEntity"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultTargetEntity"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="resolvedTargetEntity"
+          eType="#//mappings/IEntity"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="cascade" eType="#//mappings/ICascade"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="INonOwningMapping" abstract="true"
+        interface="true" eSuperTypes="#//mappings/IRelationshipMapping">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="mappedBy" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IMultiRelationshipMapping" abstract="true"
+        interface="true" eSuperTypes="#//mappings/INonOwningMapping">
+      <eOperations name="isNoOrdering" ordered="false" unique="false" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+      <eOperations name="setNoOrdering" ordered="false" unique="false"/>
+      <eOperations name="isOrderByPk" ordered="false" unique="false" lowerBound="1"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+      <eOperations name="setOrderByPk" ordered="false" unique="false"/>
+      <eOperations name="isCustomOrdering" ordered="false" unique="false" lowerBound="1"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="orderBy" ordered="false"
+          unique="false" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fetch" eType="#//mappings/DefaultLazyFetchType"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="joinTable" lowerBound="1"
+          eType="#//mappings/IJoinTable" changeable="false" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="mapKey" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IOneToMany" abstract="true" interface="true"
+        eSuperTypes="#//mappings/IMultiRelationshipMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IManyToMany" abstract="true" interface="true"
+        eSuperTypes="#//mappings/IMultiRelationshipMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ISingleRelationshipMapping" abstract="true"
+        interface="true" eSuperTypes="#//mappings/IRelationshipMapping">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fetch" eType="#//mappings/DefaultEagerFetchType"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="joinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" changeable="false" volatile="true" transient="true"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedJoinColumns"
+          upperBound="-1" eType="#//mappings/IJoinColumn" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultJoinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="optional" eType="#//mappings/DefaultTrueBoolean"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IManyToOne" abstract="true" interface="true"
+        eSuperTypes="#//mappings/ISingleRelationshipMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IOneToOne" abstract="true" interface="true"
+        eSuperTypes="#//mappings/ISingleRelationshipMapping #//mappings/INonOwningMapping"/>
+    <eClassifiers xsi:type="ecore:EEnum" name="DefaultEagerFetchType">
+      <eLiterals name="Default" literal="Default (Eager)"/>
+      <eLiterals name="EAGER" value="1" literal="Eager"/>
+      <eLiterals name="LAZY" value="2" literal="Lazy"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="DefaultLazyFetchType">
+      <eLiterals name="Default" literal="Default (Lazy)"/>
+      <eLiterals name="LAZY" value="1" literal="Lazy"/>
+      <eLiterals name="EAGER" value="2" literal="Eager"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="DefaultFalseBoolean">
+      <eLiterals name="Default" literal="Default (False)"/>
+      <eLiterals name="false" value="1" literal="False"/>
+      <eLiterals name="true" value="2" literal="True"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="DefaultTrueBoolean">
+      <eLiterals name="Default" literal="Default (True)"/>
+      <eLiterals name="true" value="1" literal="True"/>
+      <eLiterals name="false" value="2" literal="False"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="TemporalType">
+      <eLiterals name="Null" literal=""/>
+      <eLiterals name="DATE" value="1" literal="Date"/>
+      <eLiterals name="TIME" value="2" literal="Time"/>
+      <eLiterals name="TIMESTAMP" value="3" literal="Timestamp"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IJoinTable" abstract="true" interface="true"
+        eSuperTypes="#//mappings/ITable">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="joinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" changeable="false" volatile="true" transient="true"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedJoinColumns"
+          upperBound="-1" eType="#//mappings/IJoinColumn" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultJoinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="inverseJoinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" changeable="false" volatile="true" transient="true"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedInverseJoinColumns"
+          upperBound="-1" eType="#//mappings/IJoinColumn" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultInverseJoinColumns"
+          upperBound="-1" eType="#//mappings/IJoinColumn" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IAbstractJoinColumn" abstract="true"
+        interface="true" eSuperTypes="#//mappings/INamedColumn">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="referencedColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedReferencedColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultReferencedColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IJoinColumn" abstract="true" interface="true"
+        eSuperTypes="#//mappings/IAbstractColumn #//mappings/IAbstractJoinColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IOverride" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IAttributeOverride" abstract="true"
+        interface="true" eSuperTypes="#//mappings/IOverride #//mappings/IColumnMapping">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="column" lowerBound="1"
+          eType="#//mappings/IColumn" changeable="false" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IAssociationOverride" abstract="true"
+        interface="true" eSuperTypes="#//mappings/IOverride">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="joinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" changeable="false" volatile="true" transient="true"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedJoinColumns"
+          upperBound="-1" eType="#//mappings/IJoinColumn" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultJoinColumns" upperBound="-1"
+          eType="#//mappings/IJoinColumn" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IDiscriminatorColumn" abstract="true"
+        interface="true" eSuperTypes="#//mappings/INamedColumn">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="discriminatorType" eType="#//mappings/DiscriminatorType"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultLength" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="31"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedLength" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="-1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="length" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          changeable="false" volatile="true" transient="true" derived="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="InheritanceType">
+      <eLiterals name="Default" literal="Default (Single Table)"/>
+      <eLiterals name="SINGLE_TABLE" value="1" literal="Single Table"/>
+      <eLiterals name="JOINED" value="2" literal="Joined"/>
+      <eLiterals name="TABLE_PER_CLASS" value="3" literal="Table per Class"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="DiscriminatorType">
+      <eLiterals name="Default" literal="Default (String)"/>
+      <eLiterals name="STRING" value="1" literal="String"/>
+      <eLiterals name="CHAR" value="2" literal="Char"/>
+      <eLiterals name="INTEGER" value="3" literal="Integer"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ISecondaryTable" abstract="true" interface="true"
+        eSuperTypes="#//mappings/ITable">
+      <eOperations name="typeMapping" eType="#//ITypeMapping"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="primaryKeyJoinColumns"
+          upperBound="-1" eType="#//mappings/IPrimaryKeyJoinColumn" changeable="false"
+          volatile="true" transient="true" containment="true" resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedPrimaryKeyJoinColumns"
+          upperBound="-1" eType="#//mappings/IPrimaryKeyJoinColumn" containment="true"
+          resolveProxies="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="defaultPrimaryKeyJoinColumns"
+          upperBound="-1" eType="#//mappings/IPrimaryKeyJoinColumn" containment="true"
+          resolveProxies="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IPrimaryKeyJoinColumn" abstract="true"
+        interface="true" eSuperTypes="#//mappings/IAbstractJoinColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IGenerator" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="initialValue" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedInitialValue"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="-1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultInitialValue"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="allocationSize" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedAllocationSize"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          defaultValueLiteral="-1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultAllocationSize"
+          eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+          changeable="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ITableGenerator" abstract="true" interface="true"
+        eSuperTypes="#//mappings/IGenerator">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="table" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedTable" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultTable" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="catalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedCatalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultCatalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="schema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedSchema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultSchema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="pkColumnName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedPkColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultPkColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="valueColumnName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedValueColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultValueColumnName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="pkColumnValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedPkColumnValue"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultPkColumnValue"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="uniqueConstraints" upperBound="-1"
+          eType="#//mappings/IUniqueConstraint" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ISequenceGenerator" abstract="true"
+        interface="true" eSuperTypes="#//mappings/IGenerator">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sequenceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" volatile="true" derived="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedSequenceName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultSequenceName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IGeneratedValue" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" eType="#//mappings/GenerationType"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="generator" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GenerationType">
+      <eLiterals name="Default" literal="Default (Auto)"/>
+      <eLiterals name="AUTO" value="1" literal="Auto"/>
+      <eLiterals name="IDENTITY" value="2" literal="Identity"/>
+      <eLiterals name="SEQUENCE" value="3" literal="Sequence"/>
+      <eLiterals name="TABLE" value="4" literal="Table"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="EnumType">
+      <eLiterals name="Default" literal="Default (Ordinal)"/>
+      <eLiterals name="ORDINAL" value="1" literal="Ordinal"/>
+      <eLiterals name="STRING" value="2" literal="String"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IQuery" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="query" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="hints" upperBound="-1"
+          eType="#//mappings/IQueryHint" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="INamedQuery" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject #//mappings/IQuery"/>
+    <eClassifiers xsi:type="ecore:EClass" name="INamedNativeQuery" abstract="true"
+        interface="true" eSuperTypes="#//IJpaSourceObject #//mappings/IQuery">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="resultClass" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="resultSetMapping" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IQueryHint" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="CascadeType">
+      <eLiterals name="ALL" literal="All"/>
+      <eLiterals name="PERSIST" value="1" literal="Persist"/>
+      <eLiterals name="MERGE" value="2" literal="Merge"/>
+      <eLiterals name="REMOVE" value="3" literal="Remove"/>
+      <eLiterals name="REFRESH" value="4" literal="Refresh"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ICascade" abstract="true" interface="true"
+        eSuperTypes="#//IJpaSourceObject">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="all" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="persist" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="merge" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="remove" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="refresh" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EBoolean"/>
+    </eClassifiers>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/jpa/plugins/org.eclipse.jpt.core/model/old_coreModels.genmodel b/jpa/plugins/org.eclipse.jpt.core/model/old_coreModels.genmodel
new file mode 100644
index 0000000..abf3828
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/model/old_coreModels.genmodel
@@ -0,0 +1,710 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.jpt.core/src"
+    creationCommands="false" creationIcons="false" editDirectory="" editorDirectory=""
+    modelPluginID="org.eclipse.jpt.core" modelName="Core" editPluginClass="" editorPluginClass=""
+    suppressInterfaces="true" codeFormatting="true" testsDirectory="" testSuiteClass=""
+    importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0" copyrightFields="false"
+    usedGenPackages="platform:/plugin/org.eclipse.emf.ecore/model/Ecore.genmodel#//ecore">
+  <foreignModel>old_core.ecore</foreignModel>
+  <foreignModel>old_java.ecore</foreignModel>
+  <foreignModel>old_orm.ecore</foreignModel>
+  <foreignModel>old_persistence.ecore</foreignModel>
+  <genPackages prefix="JpaCore" basePackage="org.eclipse.jpt.core" disposableProviderFactory="true"
+      ecorePackage="old_core.ecore#/">
+    <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//AccessType">
+      <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//AccessType/Default"/>
+      <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//AccessType/PROPERTY"/>
+      <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//AccessType/FIELD"/>
+    </genEnums>
+    <genClasses ecoreClass="old_core.ecore#//IJpaModel"/>
+    <genClasses ecoreClass="old_core.ecore#//JpaModel">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//JpaModel/projects"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IJpaEObject">
+      <genOperations ecoreOperation="old_core.ecore#//IJpaEObject/getJpaProject"/>
+    </genClasses>
+    <genClasses image="false" ecoreClass="old_core.ecore#//JpaEObject"/>
+    <genClasses ecoreClass="old_core.ecore#//IJpaProject">
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/getModel"/>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/getPlatform"/>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/setPlatform">
+        <genParameters ecoreParameter="old_core.ecore#//IJpaProject/setPlatform/platformId"/>
+      </genOperations>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/getDataSource"/>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/setDataSource">
+        <genParameters ecoreParameter="old_core.ecore#//IJpaProject/setDataSource/connectionProfileName"/>
+      </genOperations>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/isDiscoverAnnotatedClasses"/>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaProject/setDiscoverAnnotatedClasses">
+        <genParameters ecoreParameter="old_core.ecore#//IJpaProject/setDiscoverAnnotatedClasses/discoverAnnotatedClasses"/>
+      </genOperations>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//JpaProject">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_core.ecore#//JpaProject/platform"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//JpaProject/dataSource"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//JpaProject/discoverAnnotatedClasses"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//JpaProject/files"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IJpaPlatform"/>
+    <genClasses ecoreClass="old_core.ecore#//IJpaDataSource">
+      <genOperations ecoreOperation="old_core.ecore#//IJpaDataSource/getConnectionProfileName"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//JpaDataSource">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//JpaDataSource/connectionProfileName"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IJpaFile">
+      <genOperations ecoreOperation="old_core.ecore#//IJpaFile/getContentId"/>
+      <genOperations ecoreOperation="old_core.ecore#//IJpaFile/getContent"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//JpaFile">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//JpaFile/contentId"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//JpaFile/content"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IJpaSourceObject">
+      <genOperations ecoreOperation="old_core.ecore#//IJpaSourceObject/getJpaFile"/>
+    </genClasses>
+    <genClasses image="false" ecoreClass="old_core.ecore#//IXmlEObject"/>
+    <genClasses image="false" ecoreClass="old_core.ecore#//XmlEObject"/>
+    <genClasses ecoreClass="old_core.ecore#//IJpaContentNode">
+      <genOperations ecoreOperation="old_core.ecore#//IJpaContentNode/getJpaFile"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IJpaRootContentNode">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_core.ecore#//IJpaRootContentNode/jpaFile"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IPersistentType">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//IPersistentType/mappingKey"/>
+      <genOperations ecoreOperation="old_core.ecore#//IPersistentType/getMapping"/>
+      <genOperations ecoreOperation="old_core.ecore#//IPersistentType/parentPersistentType"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//ITypeMapping">
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//ITypeMapping/name"/>
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//ITypeMapping/tableName"/>
+      <genOperations ecoreOperation="old_core.ecore#//ITypeMapping/getPersistentType"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//NullTypeMapping"/>
+    <genClasses ecoreClass="old_core.ecore#//IPersistentAttribute">
+      <genFeatures property="Readonly" notify="false" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//IPersistentAttribute/mapping"/>
+      <genOperations ecoreOperation="old_core.ecore#//IPersistentAttribute/typeMapping"/>
+      <genOperations ecoreOperation="old_core.ecore#//IPersistentAttribute/getName"/>
+      <genOperations ecoreOperation="old_core.ecore#//IPersistentAttribute/mappingKey"/>
+      <genOperations ecoreOperation="old_core.ecore#//IPersistentAttribute/defaultMappingKey"/>
+    </genClasses>
+    <genClasses ecoreClass="old_core.ecore#//IAttributeMapping">
+      <genOperations ecoreOperation="old_core.ecore#//IAttributeMapping/getPersistentAttribute"/>
+      <genOperations ecoreOperation="old_core.ecore#//IAttributeMapping/isDefault"/>
+    </genClasses>
+    <nestedGenPackages prefix="JpaCoreMappings" basePackage="org.eclipse.jpt.core.internal"
+        disposableProviderFactory="true" ecorePackage="old_core.ecore#//mappings">
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/DefaultEagerFetchType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultEagerFetchType/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultEagerFetchType/EAGER"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultEagerFetchType/LAZY"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/DefaultLazyFetchType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultLazyFetchType/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultLazyFetchType/LAZY"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultLazyFetchType/EAGER"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/DefaultFalseBoolean">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultFalseBoolean/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultFalseBoolean/false"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultFalseBoolean/true"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/DefaultTrueBoolean">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultTrueBoolean/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultTrueBoolean/true"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DefaultTrueBoolean/false"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/TemporalType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/TemporalType/Null"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/TemporalType/DATE"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/TemporalType/TIME"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/TemporalType/TIMESTAMP"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/InheritanceType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/InheritanceType/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/InheritanceType/SINGLE_TABLE"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/InheritanceType/JOINED"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/InheritanceType/TABLE_PER_CLASS"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/DiscriminatorType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DiscriminatorType/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DiscriminatorType/STRING"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DiscriminatorType/CHAR"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/DiscriminatorType/INTEGER"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/GenerationType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/GenerationType/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/GenerationType/AUTO"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/GenerationType/IDENTITY"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/GenerationType/SEQUENCE"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/GenerationType/TABLE"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/EnumType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/EnumType/Default"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/EnumType/ORDINAL"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/EnumType/STRING"/>
+      </genEnums>
+      <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_core.ecore#//mappings/CascadeType">
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/CascadeType/ALL"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/CascadeType/PERSIST"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/CascadeType/MERGE"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/CascadeType/REMOVE"/>
+        <genEnumLiterals ecoreEnumLiteral="old_core.ecore#//mappings/CascadeType/REFRESH"/>
+      </genEnums>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IMappedSuperclass">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IMappedSuperclass/idClass"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IEntity">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/specifiedName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/defaultName"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/table"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/specifiedSecondaryTables"/>
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/primaryKeyJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/specifiedPrimaryKeyJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/defaultPrimaryKeyJoinColumns"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/inheritanceStrategy"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/defaultDiscriminatorValue"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/specifiedDiscriminatorValue"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/discriminatorValue"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/discriminatorColumn"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/sequenceGenerator"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/tableGenerator"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/attributeOverrides"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/specifiedAttributeOverrides"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/defaultAttributeOverrides"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/associationOverrides"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/specifiedAssociationOverrides"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/defaultAssociationOverrides"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/namedQueries"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEntity/namedNativeQueries"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IEntity/idClass"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IEntity/discriminatorValueIsAllowed"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IEntity/getSecondaryTables"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IEntity/parentEntity"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IEntity/rootEntity"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IEmbeddable"/>
+      <genClasses ecoreClass="old_core.ecore#//mappings/ITable">
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/name"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/specifiedName"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/defaultName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/catalog"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/specifiedCatalog"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/defaultCatalog"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/schema"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/specifiedSchema"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITable/defaultSchema"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ITable/uniqueConstraints"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IUniqueConstraint">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IUniqueConstraint/columnNames"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/INamedColumn">
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INamedColumn/name"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INamedColumn/specifiedName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INamedColumn/defaultName"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INamedColumn/columnDefinition"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IAbstractColumn">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/unique"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/nullable"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/insertable"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/updatable"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/table"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/specifiedTable"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractColumn/defaultTable"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IColumn">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IColumn/length"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IColumn/specifiedLength"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IColumn/precision"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IColumn/specifiedPrecision"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IColumn/scale"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IColumn/specifiedScale"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IColumn/getDefaultLength"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IColumn/getDefaultPrecision"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IColumn/getDefaultScale"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IColumnMapping">
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IColumnMapping/getColumn"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IBasic">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IBasic/fetch"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IBasic/optional"/>
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IBasic/column"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IBasic/lob"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IBasic/temporal"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IBasic/enumerated"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IId">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IId/column"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IId/generatedValue"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IId/temporal"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IId/tableGenerator"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IId/sequenceGenerator"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/ITransient"/>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IVersion">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IVersion/column"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IVersion/temporal"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IEmbeddedId"/>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IEmbedded">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEmbedded/attributeOverrides"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEmbedded/specifiedAttributeOverrides"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IEmbedded/defaultAttributeOverrides"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IEmbedded/embeddable"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IRelationshipMapping">
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IRelationshipMapping/targetEntity"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IRelationshipMapping/specifiedTargetEntity"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IRelationshipMapping/defaultTargetEntity"/>
+        <genFeatures notify="false" createChild="false" propertySortChoices="true"
+            ecoreFeature="ecore:EReference old_core.ecore#//mappings/IRelationshipMapping/resolvedTargetEntity"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IRelationshipMapping/cascade"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/INonOwningMapping">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INonOwningMapping/mappedBy"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IMultiRelationshipMapping">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IMultiRelationshipMapping/orderBy"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IMultiRelationshipMapping/fetch"/>
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IMultiRelationshipMapping/joinTable"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IMultiRelationshipMapping/mapKey"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IMultiRelationshipMapping/isNoOrdering"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IMultiRelationshipMapping/setNoOrdering"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IMultiRelationshipMapping/isOrderByPk"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IMultiRelationshipMapping/setOrderByPk"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/IMultiRelationshipMapping/isCustomOrdering"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IOneToMany"/>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IManyToMany"/>
+      <genClasses ecoreClass="old_core.ecore#//mappings/ISingleRelationshipMapping">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ISingleRelationshipMapping/fetch"/>
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ISingleRelationshipMapping/joinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ISingleRelationshipMapping/specifiedJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ISingleRelationshipMapping/defaultJoinColumns"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ISingleRelationshipMapping/optional"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IManyToOne"/>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IOneToOne"/>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IJoinTable">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IJoinTable/joinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IJoinTable/specifiedJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IJoinTable/defaultJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IJoinTable/inverseJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IJoinTable/specifiedInverseJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IJoinTable/defaultInverseJoinColumns"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IAbstractJoinColumn">
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractJoinColumn/referencedColumnName"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractJoinColumn/specifiedReferencedColumnName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IAbstractJoinColumn/defaultReferencedColumnName"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IJoinColumn"/>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IOverride">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IOverride/name"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IAttributeOverride">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IAttributeOverride/column"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IAssociationOverride">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IAssociationOverride/joinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IAssociationOverride/specifiedJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IAssociationOverride/defaultJoinColumns"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/IDiscriminatorColumn">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IDiscriminatorColumn/discriminatorType"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IDiscriminatorColumn/defaultLength"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IDiscriminatorColumn/specifiedLength"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IDiscriminatorColumn/length"/>
+      </genClasses>
+      <genClasses ecoreClass="old_core.ecore#//mappings/ISecondaryTable">
+        <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ISecondaryTable/primaryKeyJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ISecondaryTable/specifiedPrimaryKeyJoinColumns"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ISecondaryTable/defaultPrimaryKeyJoinColumns"/>
+        <genOperations ecoreOperation="old_core.ecore#//mappings/ISecondaryTable/typeMapping"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IPrimaryKeyJoinColumn"/>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IGenerator">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/name"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/initialValue"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/specifiedInitialValue"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/defaultInitialValue"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/allocationSize"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/specifiedAllocationSize"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGenerator/defaultAllocationSize"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/ITableGenerator">
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/table"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/specifiedTable"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/defaultTable"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/catalog"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/specifiedCatalog"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/defaultCatalog"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/schema"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/specifiedSchema"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/defaultSchema"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/pkColumnName"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/specifiedPkColumnName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/defaultPkColumnName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/valueColumnName"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/specifiedValueColumnName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/defaultValueColumnName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/pkColumnValue"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/specifiedPkColumnValue"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ITableGenerator/defaultPkColumnValue"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/ITableGenerator/uniqueConstraints"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/ISequenceGenerator">
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ISequenceGenerator/sequenceName"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ISequenceGenerator/specifiedSequenceName"/>
+        <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ISequenceGenerator/defaultSequenceName"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IGeneratedValue">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGeneratedValue/strategy"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IGeneratedValue/generator"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IQuery">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IQuery/name"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IQuery/query"/>
+        <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_core.ecore#//mappings/IQuery/hints"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/INamedQuery"/>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/INamedNativeQuery">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INamedNativeQuery/resultClass"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/INamedNativeQuery/resultSetMapping"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/IQueryHint">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IQueryHint/name"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/IQueryHint/value"/>
+      </genClasses>
+      <genClasses image="false" ecoreClass="old_core.ecore#//mappings/ICascade">
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ICascade/all"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ICascade/persist"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ICascade/merge"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ICascade/remove"/>
+        <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_core.ecore#//mappings/ICascade/refresh"/>
+      </genClasses>
+    </nestedGenPackages>
+  </genPackages>
+  <genPackages prefix="JpaJava" basePackage="org.eclipse.jpt.core.internal.content"
+      disposableProviderFactory="true" ecorePackage="old_java.ecore#/">
+    <genClasses image="false" ecoreClass="old_java.ecore#//JavaEObject">
+      <genOperations ecoreOperation="old_java.ecore#//JavaEObject/getJpaFile"/>
+      <genOperations ecoreOperation="old_java.ecore#//JavaEObject/getRoot"/>
+    </genClasses>
+    <genClasses ecoreClass="old_java.ecore#//JpaCompilationUnit">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_java.ecore#//JpaCompilationUnit/types"/>
+    </genClasses>
+    <genClasses ecoreClass="old_java.ecore#//JavaPersistentType">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_java.ecore#//JavaPersistentType/mapping"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_java.ecore#//JavaPersistentType/attributes"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_java.ecore#//JavaPersistentType/access"/>
+    </genClasses>
+    <genClasses ecoreClass="old_java.ecore#//JavaPersistentAttribute">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_java.ecore#//JavaPersistentAttribute/defaultMapping"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_java.ecore#//JavaPersistentAttribute/specifiedMapping"/>
+    </genClasses>
+    <genClasses image="false" ecoreClass="old_java.ecore#//IJavaTypeMapping"/>
+    <genClasses image="false" ecoreClass="old_java.ecore#//IJavaAttributeMapping"/>
+    <nestedGenPackages prefix="JpaJavaMappings" basePackage="org.eclipse.jpt.core.internal.content.java"
+        disposableProviderFactory="true" ecorePackage="old_java.ecore#//mappings">
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaEntity"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaEmbeddable"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaMappedSuperclass"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaBasic"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaEmbedded"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaEmbeddedId"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaId"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaManyToMany"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaManyToOne"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaOneToMany"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaOneToOne"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaTransient"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/IJavaVersion"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaTypeMapping"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaEntity"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaMappedSuperclass"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaEmbeddable"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaNullTypeMapping"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaAttributeMapping"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaBasic"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaId"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaTransient"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaVersion"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaEmbeddedId"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaEmbedded"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaRelationshipMapping"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaSingleRelationshipMapping"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaManyToOne"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaOneToOne"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaMultiRelationshipMapping"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaOneToMany"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaManyToMany"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaNullAttributeMapping"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/AbstractJavaTable"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaTable"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaSecondaryTable"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaJoinTable"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaNamedColumn"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/AbstractJavaColumn"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaColumn"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaJoinColumn"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaOverride"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaAttributeOverride"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaAssociationOverride"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaDiscriminatorColumn"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaPrimaryKeyJoinColumn"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaGeneratedValue"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaGenerator"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaTableGenerator"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaSequenceGenerator"/>
+      <genClasses image="false" ecoreClass="old_java.ecore#//mappings/JavaAbstractQuery"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaNamedQuery"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaNamedNativeQuery"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaQueryHint"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaUniqueConstraint"/>
+      <genClasses ecoreClass="old_java.ecore#//mappings/JavaCascade"/>
+    </nestedGenPackages>
+  </genPackages>
+  <genPackages prefix="Orm" basePackage="org.eclipse.jpt.core.internal.content" disposableProviderFactory="true"
+      ecorePackage="old_orm.ecore#/">
+    <genClasses ecoreClass="old_orm.ecore#//XmlRootContentNode">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlRootContentNode/entityMappings"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//EntityMappingsInternal">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/root"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/version"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/description"/>
+      <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/persistenceUnitMetadataInternal"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/packageInternal"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/defaultSchema"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/specifiedSchema"/>
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/schema"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/defaultCatalog"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/specifiedCatalog"/>
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/catalog"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/defaultAccess"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/specifiedAccess"/>
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsInternal/access"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/typeMappings"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/persistentTypes"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/sequenceGenerators"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/tableGenerators"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/namedQueries"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsInternal/namedNativeQueries"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//EntityMappings">
+      <genFeatures property="Readonly" notify="false" createChild="false" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappings/persistenceUnitMetadata"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappings/package"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//EntityMappingsForXml">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//EntityMappingsForXml/persistenceUnitMetadataForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//EntityMappingsForXml/packageForXml"/>
+    </genClasses>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlTypeMapping">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlTypeMapping/defaultAccess"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlTypeMapping/specifiedAccess"/>
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlTypeMapping/access"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlTypeMapping/metadataComplete"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlTypeMapping/persistentType"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlPersistentType">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlPersistentType/class"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlPersistentType/attributeMappings"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlPersistentType/specifiedAttributeMappings"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlPersistentType/virtualAttributeMappings"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlPersistentType/persistentAttributes"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlPersistentType/specifiedPersistentAttributes"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlPersistentType/virtualPersistentAttributes"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlMappedSuperclass">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlMappedSuperclass/idClassForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlEntityInternal"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlEntityForXml">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlEntityForXml/tableForXml"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlEntityForXml/discriminatorColumnForXml"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlEntityForXml/idClassForXml"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlEntityForXml/inheritanceForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlEntity">
+      <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_orm.ecore#//XmlEntity/secondaryTables"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlEntity/virtualSecondaryTables"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlEmbeddable"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlAttributeMapping">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlAttributeMapping/persistentAttribute"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlNullAttributeMapping"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlBasic"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlId"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlTransient"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlEmbedded"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlEmbeddedId"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlVersion"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlMultiRelationshipMappingInternal"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlMultiRelationshipMappingForXml">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlMultiRelationshipMappingForXml/joinTableForXml"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//XmlMultiRelationshipMappingForXml/mapKeyForXml"/>
+    </genClasses>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlMultiRelationshipMapping"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlOneToMany"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlManyToMany"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlPersistentAttribute">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlPersistentAttribute/name"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//PersistenceUnitMetadataInternal">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitMetadataInternal/xmlMappingMetadataCompleteInternal"/>
+      <genFeatures property="None" children="true" createChild="false" ecoreFeature="ecore:EReference old_orm.ecore#//PersistenceUnitMetadataInternal/persistenceUnitDefaultsInternal"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//PersistenceUnitMetadata">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitMetadata/xmlMappingMetadataComplete"/>
+      <genFeatures property="Readonly" notify="false" createChild="false" ecoreFeature="ecore:EReference old_orm.ecore#//PersistenceUnitMetadata/persistenceUnitDefaults"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//PersistenceUnitMetadataForXml">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitMetadataForXml/xmlMappingMetadataCompleteForXml"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//PersistenceUnitMetadataForXml/persistenceUnitDefaultsForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//PersistenceUnitDefaultsInternal">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsInternal/schemaInternal"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsInternal/catalogInternal"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsInternal/accessInternal"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsInternal/cascadePersistInternal"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//PersistenceUnitDefaults">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaults/schema"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaults/catalog"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaults/access"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaults/cascadePersist"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//PersistenceUnitDefaultsForXml">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsForXml/schemaForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsForXml/catalogForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsForXml/accessForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//PersistenceUnitDefaultsForXml/cascadePersistForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlTable"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//AbstractXmlNamedColumn">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlNamedColumn/specifiedNameForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlNamedColumn/columnDefinitionForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//AbstractXmlColumn">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlColumn/uniqueForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlColumn/nullableForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlColumn/insertableForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlColumn/updatableForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlColumn/specifiedTableForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlColumn">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlColumn/lengthForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlColumn/precisionForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlColumn/scaleForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlJoinColumn">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlJoinColumn/specifiedReferencedColumnNameForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//IXmlColumnMapping">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_orm.ecore#//IXmlColumnMapping/columnForXml"/>
+      <genOperations ecoreOperation="old_orm.ecore#//IXmlColumnMapping/makeColumnForXmlNonNull"/>
+      <genOperations ecoreOperation="old_orm.ecore#//IXmlColumnMapping/makeColumnForXmlNull"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlManyToOne"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlOneToOne"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlSingleRelationshipMapping"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlRelationshipMapping"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlJoinTable"/>
+    <genClasses ecoreClass="old_orm.ecore#//AbstractXmlTable">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlTable/specifiedNameForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlTable/specifiedCatalogForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//AbstractXmlTable/specifiedSchemaForXml"/>
+    </genClasses>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlOverride"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlAttributeOverride"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlAssociationOverride"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlDiscriminatorColumn">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlDiscriminatorColumn/discriminatorTypeForXml"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlDiscriminatorColumn/specifiedLengthForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlSecondaryTable"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlPrimaryKeyJoinColumn">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlPrimaryKeyJoinColumn/specifiedReferencedColumnNameForXml"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlGeneratedValue"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//XmlGenerator"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlSequenceGenerator"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlTableGenerator"/>
+    <genClasses image="false" ecoreClass="old_orm.ecore#//AbstractXmlQuery"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlNamedQuery"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlNamedNativeQuery"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlQueryHint"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlUniqueConstraint"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlCascade"/>
+    <genClasses ecoreClass="old_orm.ecore#//XmlIdClass">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlIdClass/value"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlInheritance">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlInheritance/strategy"/>
+    </genClasses>
+    <genClasses ecoreClass="old_orm.ecore#//XmlMapKey">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_orm.ecore#//XmlMapKey/name"/>
+    </genClasses>
+  </genPackages>
+  <genPackages prefix="Persistence" basePackage="org.eclipse.jpt.core.internal.content"
+      disposableProviderFactory="true" ecorePackage="old_persistence.ecore#/">
+    <genEnums typeSafeEnumCompatible="false" ecoreEnum="old_persistence.ecore#//PersistenceUnitTransactionType">
+      <genEnumLiterals ecoreEnumLiteral="old_persistence.ecore#//PersistenceUnitTransactionType/JTA"/>
+      <genEnumLiterals ecoreEnumLiteral="old_persistence.ecore#//PersistenceUnitTransactionType/RESOURCE_LOCAL"/>
+    </genEnums>
+    <genDataTypes ecoreDataType="old_persistence.ecore#//PersistenceUnitTransactionTypeObject"/>
+    <genDataTypes ecoreDataType="old_persistence.ecore#//Version"/>
+    <genClasses ecoreClass="old_persistence.ecore#//PersistenceXmlRootContentNode">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_persistence.ecore#//PersistenceXmlRootContentNode/persistence"/>
+    </genClasses>
+    <genClasses ecoreClass="old_persistence.ecore#//Persistence">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_persistence.ecore#//Persistence/persistenceUnits"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//Persistence/version"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference old_persistence.ecore#//Persistence/root"/>
+    </genClasses>
+    <genClasses ecoreClass="old_persistence.ecore#//PersistenceUnit">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/description"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/provider"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/jtaDataSource"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/nonJtaDataSource"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EReference old_persistence.ecore#//PersistenceUnit/mappingFiles"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/jarFiles"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EReference old_persistence.ecore#//PersistenceUnit/classes"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/excludeUnlistedClasses"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_persistence.ecore#//PersistenceUnit/properties"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/name"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//PersistenceUnit/transactionType"/>
+    </genClasses>
+    <genClasses ecoreClass="old_persistence.ecore#//MappingFileRef">
+      <genFeatures property="Readonly" createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//MappingFileRef/fileName"/>
+    </genClasses>
+    <genClasses ecoreClass="old_persistence.ecore#//JavaClassRef">
+      <genFeatures property="Readonly" notify="false" createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//JavaClassRef/javaClass"/>
+    </genClasses>
+    <genClasses ecoreClass="old_persistence.ecore#//Properties">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference old_persistence.ecore#//Properties/properties"/>
+    </genClasses>
+    <genClasses ecoreClass="old_persistence.ecore#//Property">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//Property/name"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute old_persistence.ecore#//Property/value"/>
+    </genClasses>
+  </genPackages>
+</genmodel:GenModel>
diff --git a/jpa/plugins/org.eclipse.jpt.core/model/old_java.ecore b/jpa/plugins/org.eclipse.jpt.core/model/old_java.ecore
new file mode 100644
index 0000000..4140f4d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/model/old_java.ecore
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="java"
+    nsURI="jpt.java.xmi" nsPrefix="org.eclipse.jpt.core.content.java">
+  <eClassifiers xsi:type="ecore:EClass" name="JavaEObject" abstract="true" eSuperTypes="old_core.ecore#//JpaEObject old_core.ecore#//IJpaSourceObject">
+    <eOperations name="getJpaFile" eType="ecore:EClass old_core.ecore#//IJpaFile"/>
+    <eOperations name="getRoot" eType="ecore:EClass old_core.ecore#//IJpaRootContentNode"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JpaCompilationUnit" eSuperTypes="#//JavaEObject old_core.ecore#//IJpaRootContentNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="types" upperBound="-1"
+        eType="#//JavaPersistentType" containment="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JavaPersistentType" eSuperTypes="#//JavaEObject old_core.ecore#//IPersistentType">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="mapping" lowerBound="1"
+        eType="#//IJavaTypeMapping" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="attributes" upperBound="-1"
+        eType="#//JavaPersistentAttribute" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="access" eType="ecore:EEnum old_core.ecore#//AccessType"
+        changeable="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JavaPersistentAttribute" eSuperTypes="#//JavaEObject old_core.ecore#//IPersistentAttribute">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="defaultMapping" lowerBound="1"
+        eType="#//IJavaAttributeMapping" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedMapping" lowerBound="1"
+        eType="#//IJavaAttributeMapping" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IJavaTypeMapping" abstract="true" interface="true"
+      eSuperTypes="old_core.ecore#//ITypeMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="IJavaAttributeMapping" abstract="true"
+      interface="true" eSuperTypes="old_core.ecore#//IAttributeMapping"/>
+  <eSubpackages name="mappings" nsURI="jpt.core.java.mappings.xmi" nsPrefix="jpt.core.java.mappings">
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaEntity" abstract="true" interface="true"
+        eSuperTypes="#//IJavaTypeMapping old_core.ecore#//mappings/IEntity"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaEmbeddable" abstract="true" interface="true"
+        eSuperTypes="#//IJavaTypeMapping old_core.ecore#//mappings/IEmbeddable"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaMappedSuperclass" abstract="true"
+        interface="true" eSuperTypes="#//IJavaTypeMapping old_core.ecore#//mappings/IMappedSuperclass"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaBasic" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IBasic"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaEmbedded" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IEmbedded"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaEmbeddedId" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IEmbeddedId"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaId" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IId"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaManyToMany" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IManyToMany"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaManyToOne" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IManyToOne"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaOneToMany" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IOneToMany"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaOneToOne" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IOneToOne"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaTransient" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/ITransient"/>
+    <eClassifiers xsi:type="ecore:EClass" name="IJavaVersion" abstract="true" interface="true"
+        eSuperTypes="#//IJavaAttributeMapping old_core.ecore#//mappings/IVersion"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaTypeMapping" abstract="true" eSuperTypes="#//JavaEObject #//IJavaTypeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaEntity" eSuperTypes="#//mappings/JavaTypeMapping #//mappings/IJavaEntity"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaMappedSuperclass" eSuperTypes="#//mappings/JavaTypeMapping #//mappings/IJavaMappedSuperclass"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaEmbeddable" eSuperTypes="#//mappings/JavaTypeMapping #//mappings/IJavaEmbeddable"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaNullTypeMapping" eSuperTypes="#//mappings/JavaTypeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaAttributeMapping" abstract="true"
+        eSuperTypes="#//JavaEObject #//IJavaAttributeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaBasic" eSuperTypes="#//mappings/JavaAttributeMapping #//mappings/IJavaBasic"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaId" eSuperTypes="#//mappings/JavaAttributeMapping #//mappings/IJavaId"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaTransient" eSuperTypes="#//mappings/JavaAttributeMapping #//mappings/IJavaTransient"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaVersion" eSuperTypes="#//mappings/JavaAttributeMapping #//mappings/IJavaVersion"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaEmbeddedId" eSuperTypes="#//mappings/JavaAttributeMapping #//mappings/IJavaEmbeddedId"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaEmbedded" eSuperTypes="#//mappings/JavaAttributeMapping #//mappings/IJavaEmbedded"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaRelationshipMapping" abstract="true"
+        eSuperTypes="#//mappings/JavaAttributeMapping old_core.ecore#//mappings/IRelationshipMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaSingleRelationshipMapping" abstract="true"
+        eSuperTypes="#//mappings/JavaRelationshipMapping old_core.ecore#//mappings/ISingleRelationshipMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaManyToOne" eSuperTypes="#//mappings/JavaSingleRelationshipMapping #//mappings/IJavaManyToOne"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaOneToOne" eSuperTypes="#//mappings/JavaSingleRelationshipMapping #//mappings/IJavaOneToOne"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaMultiRelationshipMapping" abstract="true"
+        eSuperTypes="#//mappings/JavaRelationshipMapping old_core.ecore#//mappings/IMultiRelationshipMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaOneToMany" eSuperTypes="#//mappings/JavaMultiRelationshipMapping #//mappings/IJavaOneToMany"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaManyToMany" eSuperTypes="#//mappings/JavaMultiRelationshipMapping #//mappings/IJavaManyToMany"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaNullAttributeMapping" eSuperTypes="#//mappings/JavaAttributeMapping"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AbstractJavaTable" abstract="true"
+        eSuperTypes="#//JavaEObject old_core.ecore#//mappings/ITable"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaTable" eSuperTypes="#//mappings/AbstractJavaTable"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaSecondaryTable" eSuperTypes="#//mappings/AbstractJavaTable old_core.ecore#//mappings/ISecondaryTable"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaJoinTable" eSuperTypes="#//mappings/AbstractJavaTable old_core.ecore#//mappings/IJoinTable"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaNamedColumn" abstract="true" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/INamedColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="AbstractJavaColumn" abstract="true"
+        eSuperTypes="#//mappings/JavaNamedColumn old_core.ecore#//mappings/IAbstractColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaColumn" eSuperTypes="#//mappings/AbstractJavaColumn old_core.ecore#//mappings/IColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaJoinColumn" eSuperTypes="#//mappings/AbstractJavaColumn old_core.ecore#//mappings/IJoinColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaOverride" abstract="true" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/IOverride"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaAttributeOverride" eSuperTypes="#//mappings/JavaOverride old_core.ecore#//mappings/IAttributeOverride"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaAssociationOverride" eSuperTypes="#//mappings/JavaOverride old_core.ecore#//mappings/IAssociationOverride"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaDiscriminatorColumn" eSuperTypes="#//mappings/JavaNamedColumn old_core.ecore#//mappings/IDiscriminatorColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaPrimaryKeyJoinColumn" eSuperTypes="#//mappings/JavaNamedColumn old_core.ecore#//mappings/IPrimaryKeyJoinColumn"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaGeneratedValue" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/IGeneratedValue"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaGenerator" abstract="true" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/IGenerator"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaTableGenerator" eSuperTypes="#//mappings/JavaGenerator old_core.ecore#//mappings/ITableGenerator"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaSequenceGenerator" eSuperTypes="#//mappings/JavaGenerator old_core.ecore#//mappings/ISequenceGenerator"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaAbstractQuery" abstract="true"
+        eSuperTypes="#//JavaEObject old_core.ecore#//mappings/IQuery"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaNamedQuery" eSuperTypes="#//mappings/JavaAbstractQuery old_core.ecore#//mappings/INamedQuery"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaNamedNativeQuery" eSuperTypes="#//mappings/JavaAbstractQuery old_core.ecore#//mappings/INamedNativeQuery"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaQueryHint" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/IQueryHint"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaUniqueConstraint" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/IUniqueConstraint"/>
+    <eClassifiers xsi:type="ecore:EClass" name="JavaCascade" eSuperTypes="#//JavaEObject old_core.ecore#//mappings/ICascade"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/jpa/plugins/org.eclipse.jpt.core/model/old_orm.ecore b/jpa/plugins/org.eclipse.jpt.core/model/old_orm.ecore
new file mode 100644
index 0000000..030f176
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/model/old_orm.ecore
@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="orm"
+    nsURI="jpt.orm.xmi" nsPrefix="org.eclipse.jpt.core.content.orm">
+  <eClassifiers xsi:type="ecore:EClass" name="XmlRootContentNode" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IJpaRootContentNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="entityMappings" ordered="false"
+        unique="false" lowerBound="1" eType="#//EntityMappingsInternal" resolveProxies="false"
+        eOpposite="#//EntityMappingsInternal/root"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="EntityMappingsInternal" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IJpaContentNode #//EntityMappingsForXml #//EntityMappings">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="root" ordered="false" unique="false"
+        lowerBound="1" eType="#//XmlRootContentNode" resolveProxies="false" eOpposite="#//XmlRootContentNode/entityMappings"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnitMetadataInternal"
+        lowerBound="1" eType="#//PersistenceUnitMetadataInternal" changeable="false"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="packageInternal" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultSchema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedSchema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="schema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        changeable="false" volatile="true" transient="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultCatalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedCatalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="catalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        changeable="false" volatile="true" transient="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultAccess" eType="ecore:EEnum old_core.ecore#//AccessType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedAccess" eType="ecore:EEnum old_core.ecore#//AccessType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="access" eType="ecore:EEnum old_core.ecore#//AccessType"
+        changeable="false" volatile="true" transient="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="typeMappings" upperBound="-1"
+        eType="#//XmlTypeMapping" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistentTypes" upperBound="-1"
+        eType="#//XmlPersistentType" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="sequenceGenerators" upperBound="-1"
+        eType="#//XmlSequenceGenerator" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="tableGenerators" upperBound="-1"
+        eType="#//XmlTableGenerator" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="namedQueries" upperBound="-1"
+        eType="#//XmlNamedQuery" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="namedNativeQueries" upperBound="-1"
+        eType="#//XmlNamedNativeQuery" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="EntityMappings" abstract="true" interface="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnitMetadata"
+        eType="#//PersistenceUnitMetadata" changeable="false" volatile="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="package" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="EntityMappingsForXml" abstract="true"
+      interface="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnitMetadataForXml"
+        eType="#//PersistenceUnitMetadataForXml" volatile="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="packageForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlTypeMapping" abstract="true" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//ITypeMapping">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="defaultAccess" eType="ecore:EEnum old_core.ecore#//AccessType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedAccess" eType="ecore:EEnum old_core.ecore#//AccessType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="access" eType="ecore:EEnum old_core.ecore#//AccessType"
+        changeable="false" volatile="true" transient="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="metadataComplete" eType="ecore:EEnum old_core.ecore#//mappings/DefaultFalseBoolean"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistentType" lowerBound="1"
+        eType="#//XmlPersistentType" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlPersistentType" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IPersistentType">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="class" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="attributeMappings" upperBound="-1"
+        eType="#//XmlAttributeMapping" changeable="false" volatile="true" transient="true"
+        containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedAttributeMappings"
+        upperBound="-1" eType="#//XmlAttributeMapping" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="virtualAttributeMappings"
+        upperBound="-1" eType="#//XmlAttributeMapping" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistentAttributes" upperBound="-1"
+        eType="#//XmlPersistentAttribute" changeable="false" volatile="true" transient="true"
+        resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="specifiedPersistentAttributes"
+        upperBound="-1" eType="#//XmlPersistentAttribute" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="virtualPersistentAttributes"
+        upperBound="-1" eType="#//XmlPersistentAttribute" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlMappedSuperclass" eSuperTypes="#//XmlTypeMapping old_core.ecore#//mappings/IMappedSuperclass">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="idClassForXml" eType="#//XmlIdClass"
+        containment="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEntityInternal" eSuperTypes="#//XmlTypeMapping #//XmlEntityForXml #//XmlEntity"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEntityForXml" abstract="true" interface="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="tableForXml" eType="#//XmlTable"
+        volatile="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="discriminatorColumnForXml"
+        eType="#//XmlDiscriminatorColumn" volatile="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="idClassForXml" eType="#//XmlIdClass"
+        containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="inheritanceForXml" eType="#//XmlInheritance"
+        containment="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEntity" abstract="true" interface="true"
+      eSuperTypes="old_core.ecore#//mappings/IEntity">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="secondaryTables" upperBound="-1"
+        eType="ecore:EClass old_core.ecore#//mappings/ISecondaryTable" changeable="false"
+        volatile="true" transient="true" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="virtualSecondaryTables"
+        upperBound="-1" eType="ecore:EClass old_core.ecore#//mappings/ISecondaryTable"
+        containment="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEmbeddable" eSuperTypes="#//XmlTypeMapping old_core.ecore#//mappings/IEmbeddable"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlAttributeMapping" abstract="true"
+      eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IAttributeMapping">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistentAttribute" lowerBound="1"
+        eType="#//XmlPersistentAttribute" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlNullAttributeMapping" eSuperTypes="#//XmlAttributeMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlBasic" eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/IBasic #//IXmlColumnMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlId" eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/IId #//IXmlColumnMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlTransient" eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/ITransient"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEmbedded" eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/IEmbedded"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlEmbeddedId" eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/IEmbeddedId"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlVersion" eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/IVersion #//IXmlColumnMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlMultiRelationshipMappingInternal"
+      abstract="true" eSuperTypes="#//XmlRelationshipMapping old_core.ecore#//mappings/IMultiRelationshipMapping #//XmlMultiRelationshipMappingForXml #//XmlMultiRelationshipMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlMultiRelationshipMappingForXml" abstract="true"
+      interface="true">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="joinTableForXml" eType="#//XmlJoinTable"
+        volatile="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="mapKeyForXml" eType="#//XmlMapKey"
+        containment="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlMultiRelationshipMapping" abstract="true"
+      interface="true" eSuperTypes="old_core.ecore#//mappings/IMultiRelationshipMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlOneToMany" eSuperTypes="#//XmlMultiRelationshipMappingInternal old_core.ecore#//mappings/IOneToMany"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlManyToMany" eSuperTypes="#//XmlMultiRelationshipMappingInternal old_core.ecore#//mappings/IManyToMany"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlPersistentAttribute" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IPersistentAttribute">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnitMetadataInternal" eSuperTypes="old_core.ecore#//XmlEObject #//PersistenceUnitMetadataForXml #//PersistenceUnitMetadata">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="xmlMappingMetadataCompleteInternal"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnitDefaultsInternal"
+        lowerBound="1" eType="#//PersistenceUnitDefaultsInternal" changeable="false"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnitMetadata" abstract="true"
+      interface="true" eSuperTypes="old_core.ecore#//IXmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="xmlMappingMetadataComplete"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnitDefaults"
+        eType="#//PersistenceUnitDefaults" changeable="false" volatile="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnitMetadataForXml" abstract="true"
+      interface="true" eSuperTypes="old_core.ecore#//IXmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="xmlMappingMetadataCompleteForXml"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnitDefaultsForXml"
+        eType="#//PersistenceUnitDefaultsForXml" volatile="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnitDefaultsInternal" eSuperTypes="old_core.ecore#//XmlEObject #//PersistenceUnitDefaults #//PersistenceUnitDefaultsForXml">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="schemaInternal" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="catalogInternal" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="accessInternal" eType="ecore:EEnum old_core.ecore#//AccessType"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="cascadePersistInternal"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnitDefaults" abstract="true"
+      interface="true" eSuperTypes="old_core.ecore#//IXmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="schema" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="catalog" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="access" eType="ecore:EEnum old_core.ecore#//AccessType"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="cascadePersist" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"
+        volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnitDefaultsForXml" abstract="true"
+      interface="true" eSuperTypes="old_core.ecore#//IXmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="schemaForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="catalogForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="accessForXml" eType="ecore:EEnum old_core.ecore#//AccessType"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="cascadePersistForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"
+        volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlTable" eSuperTypes="#//AbstractXmlTable old_core.ecore#//mappings/ITable"/>
+  <eClassifiers xsi:type="ecore:EClass" name="AbstractXmlNamedColumn" abstract="true"
+      eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/INamedColumn">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedNameForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="columnDefinitionForXml"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="AbstractXmlColumn" abstract="true" eSuperTypes="#//AbstractXmlNamedColumn old_core.ecore#//mappings/IAbstractColumn">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="uniqueForXml" eType="ecore:EEnum old_core.ecore#//mappings/DefaultFalseBoolean"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="nullableForXml" eType="ecore:EEnum old_core.ecore#//mappings/DefaultTrueBoolean"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="insertableForXml" eType="ecore:EEnum old_core.ecore#//mappings/DefaultTrueBoolean"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="updatableForXml" eType="ecore:EEnum old_core.ecore#//mappings/DefaultTrueBoolean"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedTableForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlColumn" eSuperTypes="#//AbstractXmlColumn old_core.ecore#//mappings/IColumn">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lengthForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
+        volatile="true" defaultValueLiteral="255"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="precisionForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="scaleForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
+        volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlJoinColumn" eSuperTypes="#//AbstractXmlColumn old_core.ecore#//mappings/IJoinColumn">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedReferencedColumnNameForXml"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="IXmlColumnMapping" abstract="true" interface="true"
+      eSuperTypes="old_core.ecore#//mappings/IColumnMapping">
+    <eOperations name="makeColumnForXmlNonNull"/>
+    <eOperations name="makeColumnForXmlNull"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="columnForXml" eType="#//XmlColumn"
+        volatile="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlManyToOne" eSuperTypes="#//XmlSingleRelationshipMapping old_core.ecore#//mappings/IManyToOne"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlOneToOne" eSuperTypes="#//XmlSingleRelationshipMapping old_core.ecore#//mappings/IOneToOne"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlSingleRelationshipMapping" abstract="true"
+      eSuperTypes="#//XmlRelationshipMapping old_core.ecore#//mappings/ISingleRelationshipMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlRelationshipMapping" abstract="true"
+      eSuperTypes="#//XmlAttributeMapping old_core.ecore#//mappings/IRelationshipMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlJoinTable" eSuperTypes="#//AbstractXmlTable old_core.ecore#//mappings/IJoinTable"/>
+  <eClassifiers xsi:type="ecore:EClass" name="AbstractXmlTable" abstract="true" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/ITable">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedNameForXml" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+        volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedCatalogForXml"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedSchemaForXml"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlOverride" abstract="true" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/IOverride"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlAttributeOverride" eSuperTypes="#//XmlOverride old_core.ecore#//mappings/IAttributeOverride #//IXmlColumnMapping"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlAssociationOverride" eSuperTypes="#//XmlOverride old_core.ecore#//mappings/IAssociationOverride"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlDiscriminatorColumn" eSuperTypes="#//AbstractXmlNamedColumn old_core.ecore#//mappings/IDiscriminatorColumn">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="discriminatorTypeForXml"
+        eType="ecore:EEnum old_core.ecore#//mappings/DiscriminatorType" volatile="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedLengthForXml"
+        eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EInt"
+        volatile="true" defaultValueLiteral="-1"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlSecondaryTable" eSuperTypes="#//AbstractXmlTable old_core.ecore#//mappings/ISecondaryTable"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlPrimaryKeyJoinColumn" eSuperTypes="#//AbstractXmlNamedColumn old_core.ecore#//mappings/IPrimaryKeyJoinColumn">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="specifiedReferencedColumnNameForXml"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" volatile="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlGeneratedValue" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/IGeneratedValue"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlGenerator" abstract="true" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/IGenerator"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlSequenceGenerator" eSuperTypes="#//XmlGenerator old_core.ecore#//mappings/ISequenceGenerator"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlTableGenerator" eSuperTypes="#//XmlGenerator old_core.ecore#//mappings/ITableGenerator"/>
+  <eClassifiers xsi:type="ecore:EClass" name="AbstractXmlQuery" abstract="true" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/IQuery"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlNamedQuery" eSuperTypes="#//AbstractXmlQuery old_core.ecore#//mappings/INamedQuery"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlNamedNativeQuery" eSuperTypes="#//AbstractXmlQuery old_core.ecore#//mappings/INamedNativeQuery"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlQueryHint" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/IQueryHint"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlUniqueConstraint" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/IUniqueConstraint"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlCascade" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//mappings/ICascade"/>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlIdClass" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlInheritance" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" eType="ecore:EEnum old_core.ecore#//mappings/InheritanceType"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="XmlMapKey" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/jpa/plugins/org.eclipse.jpt.core/model/old_persistence.ecore b/jpa/plugins/org.eclipse.jpt.core/model/old_persistence.ecore
new file mode 100644
index 0000000..4deccb1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/model/old_persistence.ecore
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="persistence"
+    nsURI="persistence.xmi" nsPrefix="org.eclipse.jpt.core.content.persistence">
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceXmlRootContentNode" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IJpaRootContentNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistence" eType="#//Persistence"
+        eOpposite="#//Persistence/root"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Persistence" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IJpaContentNode">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="persistenceUnits" upperBound="-1"
+        eType="#//PersistenceUnit" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" unique="false"
+        lowerBound="1" eType="#//Version"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="root" ordered="false" unique="false"
+        lowerBound="1" eType="#//PersistenceXmlRootContentNode" resolveProxies="false"
+        eOpposite="#//PersistenceXmlRootContentNode/persistence"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="PersistenceUnit" eSuperTypes="old_core.ecore#//XmlEObject old_core.ecore#//IJpaContentNode">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="provider" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="jtaDataSource" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="nonJtaDataSource" unique="false"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="mappingFiles" unique="false"
+        upperBound="-1" eType="#//MappingFileRef" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="jarFiles" unique="false"
+        upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="classes" unique="false"
+        upperBound="-1" eType="#//JavaClassRef" containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="excludeUnlistedClasses"
+        unique="false" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Boolean"
+        defaultValueLiteral="false" unsettable="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="properties" eType="#//Properties"
+        containment="true" resolveProxies="false"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="transactionType" unique="false"
+        eType="#//PersistenceUnitTransactionType" defaultValueLiteral="JTA" unsettable="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="MappingFileRef" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="fileName" ordered="false"
+        unique="false" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"
+        defaultValueLiteral=""/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="JavaClassRef" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="javaClass" ordered="false"
+        unique="false" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Properties" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="properties" upperBound="-1"
+        eType="#//Property" containment="true" resolveProxies="false"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Property" eSuperTypes="old_core.ecore#//XmlEObject">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" unique="false" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="PersistenceUnitTransactionType">
+    <eLiterals name="JTA"/>
+    <eLiterals name="RESOURCE_LOCAL" value="1"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EDataType" name="PersistenceUnitTransactionTypeObject"
+      instanceClassName="org.eclipse.emf.common.util.Enumerator"/>
+  <eClassifiers xsi:type="ecore:EDataType" name="Version" instanceClassName="java.lang.String"/>
+</ecore:EPackage>
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/IJpaFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/IJpaFactory.java
new file mode 100644
index 0000000..57d388e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/IJpaFactory.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0, which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal;
+
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaBasic;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbeddable;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbedded;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbeddedId;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEntity;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaId;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaManyToMany;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaManyToOne;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaMappedSuperclass;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaOneToMany;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaOneToOne;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaTransient;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaVersion;
+import org.eclipse.jpt.core.internal.jdtutility.Attribute;
+import org.eclipse.jpt.core.internal.jdtutility.Type;
+import org.eclipse.jpt.core.internal.platform.BaseJpaFactory;
+
+/**
+ * Use IJpaFactory to create any IJavaTypeMapping or IJavaAttributeMappings.  This is necessary
+ * so that platforms can extend the java model with their own annotations. 
+ * IJavaTypeMappingProvider and IJavaAttributeMappingProvider use this factory.
+ * See IJpaPlatform.javaTypeMappingProviders() and IJpaPlatform.javaAttributeMappingProviders()
+ * for creating new mappings types.
+ * @see BaseJpaFactory
+ */
+public interface IJpaFactory
+{
+	IJavaEntity createJavaEntity(Type type);
+	
+	IJavaEmbeddable createJavaEmbeddable(Type type);
+	
+	IJavaMappedSuperclass createJavaMappedSuperclass(Type type);
+		
+	IJavaBasic createJavaBasic(Attribute attribute);
+	
+	IJavaEmbedded createJavaEmbedded(Attribute attribute);
+	
+	IJavaEmbeddedId createJavaEmbeddedId(Attribute attribute);
+	
+	IJavaId createJavaId(Attribute attribute);
+	
+	IJavaManyToMany createJavaManyToMany(Attribute attribute);
+	
+	IJavaManyToOne createJavaManyToOne(Attribute attribute);
+	
+	IJavaOneToMany createJavaOneToMany(Attribute attribute);
+	
+	IJavaOneToOne createJavaOneToOne(Attribute attribute);
+	
+	IJavaTransient createJavaTransient(Attribute attribute);
+	
+	IJavaVersion createJavaVersion(Attribute attribute);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/IDefaultJavaAttributeMappingProvider.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/IDefaultJavaAttributeMappingProvider.java
new file mode 100644
index 0000000..017fbd6
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/IDefaultJavaAttributeMappingProvider.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java;
+
+import org.eclipse.jpt.core.internal.jdtutility.Attribute;
+import org.eclipse.jpt.core.internal.platform.DefaultsContext;
+
+/**
+ * Map a string key to an attribute mapping and its corresponding
+ * Java annotation adapter.  
+ */
+public interface IDefaultJavaAttributeMappingProvider extends IJavaAttributeMappingProvider {
+
+	/**
+	 * Given the Attribute and DefaultContext return whether the default mapping applies.
+	 * This will be used to determine the default mapping in the case where no 
+	 * mapping has been specified.
+	 * @param attribute
+	 * @param defaultsContext
+	 * @return
+	 */
+	boolean defaultApplies(Attribute attribute, DefaultsContext defaultsContext);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaBasic.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaBasic.java
new file mode 100644
index 0000000..5076220
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaBasic.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IBasic;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Basic</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaBasic()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaBasic extends IJavaAttributeMapping, IBasic
+{} // IJavaBasic
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbeddable.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbeddable.java
new file mode 100644
index 0000000..46da23c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbeddable.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaTypeMapping;
+import org.eclipse.jpt.core.internal.mappings.IEmbeddable;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Embeddable</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaEmbeddable()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaEmbeddable extends IJavaTypeMapping, IEmbeddable
+{} // IJavaEmbeddable
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbedded.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbedded.java
new file mode 100644
index 0000000..f92b980
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbedded.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IEmbedded;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Embedded</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaEmbedded()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaEmbedded extends IJavaAttributeMapping, IEmbedded
+{} // IJavaEmbedded
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbeddedId.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbeddedId.java
new file mode 100644
index 0000000..f1f53c9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEmbeddedId.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IEmbeddedId;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Embedded Id</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaEmbeddedId()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaEmbeddedId extends IJavaAttributeMapping, IEmbeddedId
+{} // IJavaEmbeddedId
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEntity.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEntity.java
new file mode 100644
index 0000000..ed775f7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaEntity.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaTypeMapping;
+import org.eclipse.jpt.core.internal.mappings.IEntity;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Entity</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaEntity()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaEntity extends IJavaTypeMapping, IEntity
+{} // IJavaEntity
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaId.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaId.java
new file mode 100644
index 0000000..1cf5cb0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaId.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IId;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Id</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaId()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaId extends IJavaAttributeMapping, IId
+{} // IJavaId
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaManyToMany.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaManyToMany.java
new file mode 100644
index 0000000..321f9bf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaManyToMany.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IManyToMany;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Many To Many</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaManyToMany()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaManyToMany extends IJavaAttributeMapping, IManyToMany
+{} // IJavaManyToMany
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaManyToOne.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaManyToOne.java
new file mode 100644
index 0000000..094266e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaManyToOne.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IManyToOne;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Many To One</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaManyToOne()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaManyToOne extends IJavaAttributeMapping, IManyToOne
+{} // IJavaManyToOne
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaMappedSuperclass.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaMappedSuperclass.java
new file mode 100644
index 0000000..3229645
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaMappedSuperclass.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaTypeMapping;
+import org.eclipse.jpt.core.internal.mappings.IMappedSuperclass;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Mapped Superclass</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaMappedSuperclass()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaMappedSuperclass
+	extends IJavaTypeMapping, IMappedSuperclass
+{} // IJavaMappedSuperclass
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaOneToMany.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaOneToMany.java
new file mode 100644
index 0000000..8f3496d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaOneToMany.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IOneToMany;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava One To Many</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaOneToMany()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaOneToMany extends IJavaAttributeMapping, IOneToMany
+{} // IJavaOneToMany
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaOneToOne.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaOneToOne.java
new file mode 100644
index 0000000..43daf73
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaOneToOne.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IOneToOne;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava One To One</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaOneToOne()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaOneToOne extends IJavaAttributeMapping, IOneToOne
+{} // IJavaOneToOne
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaTransient.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaTransient.java
new file mode 100644
index 0000000..02df56e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaTransient.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.ITransient;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Transient</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaTransient()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaTransient extends IJavaAttributeMapping, ITransient
+{} // IJavaTransient
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaVersion.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaVersion.java
new file mode 100644
index 0000000..e5e9e68
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/java/mappings/IJavaVersion.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.content.java.mappings;
+
+import org.eclipse.jpt.core.internal.content.java.IJavaAttributeMapping;
+import org.eclipse.jpt.core.internal.mappings.IVersion;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>IJava Version</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ *
+ * @see org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsPackage#getIJavaVersion()
+ * @model kind="class" interface="true" abstract="true"
+ * @generated
+ */
+public interface IJavaVersion extends IJavaAttributeMapping, IVersion
+{} // IJavaVersion
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/OrmInit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/OrmInit.java
new file mode 100644
index 0000000..b93a2b8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/OrmInit.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ *  Copyright (c) 2005, 2007 Oracle. All rights reserved.  This program and 
+ *  the accompanying materials are made available under the terms of the 
+ *  Eclipse Public License v1.0 which accompanies this distribution, and is 
+ *  available at http://www.eclipse.org/legal/epl-v10.html
+ *  
+ *  Contributors: 
+ *  	Oracle - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.content.orm;
+
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.jpt.core.internal.content.orm.resource.OrmXmlResourceFactory;
+import org.eclipse.wst.common.componentcore.internal.impl.WTPEntityResolver;
+import org.eclipse.wst.common.internal.emf.utilities.DOMUtilities;
+import org.eclipse.wst.common.internal.emf.utilities.ExtendedEcoreUtil;
+
+public class OrmInit
+{
+	private static boolean initialized = false;
+	
+	public static void init() {
+		init(true);
+	}
+	
+	public static void init(boolean shouldPreregisterPackages) {
+		if (! initialized) {
+			initialized = true;
+			DOMUtilities.setDefaultEntityResolver(WTPEntityResolver.INSTANCE);
+			initResourceFactories();
+		}
+		if (shouldPreregisterPackages) {
+			preregisterPackages();
+		}
+	}
+	
+	private static void initResourceFactories() {
+		OrmXmlResourceFactory.register();
+	}
+	
+	private static void preregisterPackages() {
+		ExtendedEcoreUtil.preRegisterPackage(
+			"orm.xmi", //$NON-NLS-1$
+			new EPackage.Descriptor() { 
+				public EPackage getEPackage() {
+					return OrmPackage.eINSTANCE;
+				}
+				
+				public EFactory getEFactory() {
+					return OrmFactory.eINSTANCE;
+				}
+			}
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/AbstractSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/OrmXmlResource.java
similarity index 61%
rename from jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/AbstractSelectionParticipant.java
rename to jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/OrmXmlResource.java
index 52408ef..6f6d02c 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/AbstractSelectionParticipant.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/OrmXmlResource.java
@@ -6,15 +6,15 @@
  * 
  * Contributors: Oracle. - initial API and implementation
  *******************************************************************************/
-package org.eclipse.jpt.ui.internal.selection;
+package org.eclipse.jpt.core.internal.content.orm;
 
-public abstract class AbstractSelectionParticipant 
-	implements ISelectionParticipant 
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
+
+
+public interface OrmXmlResource extends TranslatorResource
 {
-	protected ISelectionManager selectionManager;
-	
-	
-	protected AbstractSelectionParticipant(ISelectionManager theSelectionManager) {
-		selectionManager = theSelectionManager;
-	}
+	/**
+	 * Return the root object
+	 */
+	EntityMappingsInternal getXmlFileContent();
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/resource/OrmXmlResourceFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/resource/OrmXmlResourceFactory.java
new file mode 100644
index 0000000..00b4b8f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/resource/OrmXmlResourceFactory.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.content.orm.resource;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.wst.common.componentcore.internal.impl.WTPResourceFactoryRegistry;
+import org.eclipse.wst.common.internal.emf.resource.Renderer;
+import org.eclipse.wst.common.internal.emf.resource.RendererFactory;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResourceFactory;
+import org.eclipse.wst.xml.core.internal.emf2xml.EMF2DOMSSERendererFactory;
+
+public class OrmXmlResourceFactory extends TranslatorResourceFactory
+{	
+	public static final String ORM_XML_FILE_NAME = "orm.xml"; //$NON-NLS-1$
+	public static final URI ORM_XML_FILE_URI = URI.createURI(ORM_XML_FILE_NAME); //$NON-NLS-1$
+
+	/**
+	 * Register myself with the Resource.Factory.Registry
+	 */
+	public static void registerWith(RendererFactory rendererFactory) {
+		WTPResourceFactoryRegistry.INSTANCE.registerLastFileSegment(ORM_XML_FILE_NAME, new OrmXmlResourceFactory(rendererFactory));
+	}
+	
+	/**
+	 * Register myself using the default renderer factory.
+	 * @see #registerWith(RendererFactory)
+	 */
+	public static void register() {
+		registerWith(EMF2DOMSSERendererFactory.INSTANCE);
+	}
+	
+	public static Resource.Factory getRegisteredFactory() {
+		return WTPResourceFactoryRegistry.INSTANCE.getFactory(ORM_XML_FILE_URI);
+	}
+
+	
+	public OrmXmlResourceFactory(RendererFactory aRendererFactory, boolean listeningForUpdates) {
+		super(aRendererFactory, listeningForUpdates);
+	}
+
+	public OrmXmlResourceFactory(RendererFactory aRendererFactory) {
+		super(aRendererFactory);
+	}
+	
+	/**
+	 * @see TranslatorResourceFactory#createResource(URI, Renderer)
+	 */
+	protected TranslatorResource createResource(URI uri, Renderer renderer) {
+		return new OrmXmlResourceImpl(uri, renderer);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/resource/OrmXmlResourceImpl.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/resource/OrmXmlResourceImpl.java
new file mode 100644
index 0000000..62f1eab
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/orm/resource/OrmXmlResourceImpl.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.content.orm.resource;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jpt.core.internal.content.orm.EntityMappingsInternal;
+import org.eclipse.jpt.core.internal.content.orm.OrmXmlResource;
+import org.eclipse.wst.common.internal.emf.resource.Renderer;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResourceImpl;
+
+public class OrmXmlResourceImpl extends TranslatorResourceImpl
+	implements OrmXmlResource
+{
+
+	private Translator rootTranslator;
+	
+	public OrmXmlResourceImpl(Renderer aRenderer) {
+		super(aRenderer);
+	}
+
+	public OrmXmlResourceImpl(URI uri, Renderer aRenderer) {
+		super(uri, aRenderer);
+	}
+	
+	/**
+	 * @see TranslatorResourceImpl#getDefaultPublicId() 
+	 */
+	protected String getDefaultPublicId() {
+		return null;
+		// only applicable for DTD-based files
+	}
+	
+	/**
+	 * @see TranslatorResourceImpl#getDefaultSystemId() 
+	 */
+	protected String getDefaultSystemId() {
+		return null;
+		// only applicable for DTD-based files
+	}
+	
+	/**
+	 * @see TranslatorResourceImpl#getDefaultVersionId() 
+	 */
+	protected int getDefaultVersionID() {
+		return 10;
+		// this seems to be the default version of the spec for this doc
+		// and the id 10 maps to the version 1.0
+	}
+	
+	/**
+	 * @see TranslatorResource#getDoctype() 
+	 */
+	public String getDoctype() {
+		return null;
+		// only applicable for DTD-based files
+	}
+	
+	/**
+	 * @see TranslatorResource#getRootTranslator() 
+	 */
+	public Translator getRootTranslator() {
+		if (this.rootTranslator == null) {
+			this.rootTranslator = buildRootTranslator();
+		}
+		return this.rootTranslator;
+	}
+	
+	protected Translator buildRootTranslator() {
+		return new EntityMappingsTranslator();
+	}
+	
+	/**
+	 * @see OrmXmlResource#getXmlFileContent()
+	 */
+	public EntityMappingsInternal getXmlFileContent() {
+		return (EntityMappingsInternal) getRootObject();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/persistence/PersistenceInit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/persistence/PersistenceInit.java
new file mode 100644
index 0000000..462191e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/persistence/PersistenceInit.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.content.persistence;
+
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.jpt.core.internal.content.persistence.resource.PersistenceXmlResourceFactory;
+import org.eclipse.wst.common.componentcore.internal.impl.WTPEntityResolver;
+import org.eclipse.wst.common.internal.emf.utilities.DOMUtilities;
+import org.eclipse.wst.common.internal.emf.utilities.ExtendedEcoreUtil;
+
+public class PersistenceInit
+{
+	private static boolean initialized = false;
+	
+	public static void init() {
+		init(true);
+	}
+	
+	public static void init(boolean shouldPreregisterPackages) {
+		if (! initialized) {
+			initialized = true;
+			DOMUtilities.setDefaultEntityResolver(WTPEntityResolver.INSTANCE);
+			initResourceFactories();
+		}
+		if (shouldPreregisterPackages) {
+			preregisterPackages();
+		}
+	}
+	
+	private static void initResourceFactories() {
+		PersistenceXmlResourceFactory.register();
+	}
+	
+	private static void preregisterPackages() {
+		ExtendedEcoreUtil.preRegisterPackage(
+			"packaging.xmi", //$NON-NLS-1$
+			new EPackage.Descriptor() { 
+				public EPackage getEPackage() {
+					return PersistencePackage.eINSTANCE;
+				}
+				
+				public EFactory getEFactory() {
+					return PersistenceFactory.eINSTANCE;
+				}
+			}
+		);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/persistence/resource/PersistenceXmlResourceFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/persistence/resource/PersistenceXmlResourceFactory.java
new file mode 100644
index 0000000..ee8a066
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/content/persistence/resource/PersistenceXmlResourceFactory.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.content.persistence.resource;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.wst.common.componentcore.internal.impl.WTPResourceFactoryRegistry;
+import org.eclipse.wst.common.internal.emf.resource.Renderer;
+import org.eclipse.wst.common.internal.emf.resource.RendererFactory;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResourceFactory;
+import org.eclipse.wst.xml.core.internal.emf2xml.EMF2DOMSSERendererFactory;
+
+public class PersistenceXmlResourceFactory extends TranslatorResourceFactory
+{
+	public static final String PERSISTENCE_XML_FILE_NAME = "persistence.xml"; //$NON-NLS-1$
+	public static final URI PERSISTENCE_XML_FILE_URI = URI.createURI(PERSISTENCE_XML_FILE_NAME); //$NON-NLS-1$
+
+	/**
+	 * Register myself with the Resource.Factory.Registry
+	 */
+	public static void registerWith(RendererFactory rendererFactory) {
+		WTPResourceFactoryRegistry.INSTANCE.registerLastFileSegment(PERSISTENCE_XML_FILE_NAME, new PersistenceXmlResourceFactory(rendererFactory));
+	}
+	
+	/**
+	 * Register myself using the default renderer factory.
+	 * @see #registerWith(RendererFactory)
+	 */
+	public static void register() {
+		registerWith(EMF2DOMSSERendererFactory.INSTANCE);
+	}
+	
+	public static Resource.Factory getRegisteredFactory() {
+		return WTPResourceFactoryRegistry.INSTANCE.getFactory(PERSISTENCE_XML_FILE_URI);
+	}
+	
+	public PersistenceXmlResourceFactory(RendererFactory aRendererFactory, boolean listeningForUpdates) {
+		super(aRendererFactory, listeningForUpdates);
+	}
+
+	public PersistenceXmlResourceFactory(RendererFactory aRendererFactory) {
+		super(aRendererFactory);
+	}
+	
+	/**
+	 * @see TranslatorResourceFactory#createResource(URI, Renderer)
+	 */
+	protected TranslatorResource createResource(URI uri, Renderer renderer) {
+		return new PersistenceResource(uri, renderer);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/jdtutility/DefaultAnnotationEditFormatter.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/jdtutility/DefaultAnnotationEditFormatter.java
new file mode 100644
index 0000000..ff2e215
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/jdtutility/DefaultAnnotationEditFormatter.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.jdtutility;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * This implementation will clean up some of the nasty Eclipse annotation
+ * formatting (or lack thereof); e.g. arrays of annotations.
+ */
+public final class DefaultAnnotationEditFormatter
+	implements AnnotationEditFormatter
+{
+	private static DefaultAnnotationEditFormatter INSTANCE = new DefaultAnnotationEditFormatter();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static DefaultAnnotationEditFormatter instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private DefaultAnnotationEditFormatter() {
+		super();
+	}
+
+	/**
+	 * TODO
+	 */
+	public void format(IDocument doc, TextEdit editTree) throws MalformedTreeException, BadLocationException {
+		TextEdit[] edits = editTree.getChildren();
+		int len = edits.length;
+		if (len == 0) {
+			return;
+		}
+
+		MultiTextEdit extraEdits = new MultiTextEdit();
+		for (int i = 0; i < len; i++) {
+			TextEdit edit1 = edits[i];
+			if ( ! (edit1 instanceof InsertEdit)) {
+				continue;  // if the edit is not an insert, skip to the next edit
+			}
+			InsertEdit insert1 = (InsertEdit) edit1;
+			int j = i + 1;
+			if (j < len) {
+				TextEdit edit2 = edits[j];
+				if (edit2 instanceof InsertEdit) {
+					InsertEdit insert2 = (InsertEdit) edit2;
+					String text1 = insert1.getText();
+					String text2 = insert2.getText();
+					int offset1 = insert1.getOffset();
+					int offset2 = insert2.getOffset();
+					if (this.stringIsAnnotation(text1) && text2.equals(" ")) {
+						// an annotation was inserted before something on the same line;
+						// replace the trailing space with a newline and appropriate indent
+						extraEdits.addChild(new ReplaceEdit(offset2, 1, this.buildCR(doc, offset2)));
+						i++;  // jump the index past 'edit2'
+						continue;  // go to the next edit
+					}
+					int comma1Length = this.commaLength(text1);
+					if ((comma1Length != 0) && this.stringIsAnnotation(text2)) {
+						// an annotation was inserted in an array initializer on the
+						// same line as the previous array element;
+						// replace the preceding space with a newline and appropriate indent
+						extraEdits.addChild(new ReplaceEdit(offset1 + comma1Length, text1.length() - comma1Length, this.buildCR(doc, offset1)));
+						i++;  // jump the index past 'edit2'
+						continue;  // go to the next edit
+					}
+				}
+			}
+			this.formatArrayInitializer(doc, insert1, extraEdits);
+		}
+		extraEdits.apply(doc, TextEdit.NONE);
+	}
+
+	/**
+	 * If the insert edit is inserting an annotation containing an array of annotations as
+	 * its value then format them nicely.
+	 */
+	private void formatArrayInitializer(IDocument doc, InsertEdit insertEdit, MultiTextEdit extraEdits) throws BadLocationException {
+		String s = insertEdit.getText();
+		if ( ! this.stringIsAnnotation(s)) {
+			return;
+		}
+		int len = s.length();
+		int pos = 1;  // skip '@'
+		while (pos < len) {
+			char c = s.charAt(pos);
+			pos++;  // bump to just past first '('
+			if (c == '(') {
+				break;
+			}
+		}
+		if (pos == len) {
+			return;  // reached end of string
+		}
+		while (pos < len) {
+			char c = s.charAt(pos);
+			pos++;  // bump to just past first '{'
+			if (c == '{') {
+				break;
+			}
+			if (c != ' ') {
+				return;
+			}
+		}
+		if (pos == len) {
+			return;  // reached end of string
+		}
+		// now look for '@' not inside parentheses and put in 
+		// line delimeter and indent string before each
+		int offset = insertEdit.getOffset();
+		String indent = null;
+		int parenDepth = 0;
+		while (pos < len) {
+			switch (s.charAt(pos)) {
+				case '(' :
+					parenDepth++;
+					break;
+				case ')' :
+					parenDepth--;
+					break;
+				case '@' :
+					if (parenDepth == 0) {
+						if (indent == null) {
+							indent = this.buildCR(doc, offset, "\t");  // TODO use tab preference?
+						}
+						extraEdits.addChild(new InsertEdit(offset + pos, indent));
+					}
+					break;
+				case '}' :
+					if (parenDepth == 0) {
+						extraEdits.addChild(new InsertEdit(offset + pos, this.buildCR(doc, offset)));
+					}
+					break;
+			}
+			pos++;
+		}
+	}
+
+	/**
+	 * Build a string containing a line delimeter and indenting characters 
+	 * matching the indent level of the line containing the character offset
+	 * (i.e. the new line's indent matches the current line).
+	 */
+	private String buildCR(IDocument doc, int offset) throws BadLocationException {
+		return this.buildCR(doc, offset, "");
+	}
+
+	private String buildCR(IDocument doc, int offset, String suffix) throws BadLocationException {
+		int line = doc.getLineOfOffset(offset);
+		StringBuffer sb = new StringBuffer();
+		sb.append(doc.getLineDelimiter(line));  // use same CR as current line
+
+		int o = doc.getLineOffset(line);  // match the whitespace of the current line
+		char c = doc.getChar(o++);
+		while ((c == ' ') || (c == '\t')) {
+			sb.append(c);
+			c = doc.getChar(o++);
+		}
+		sb.append(suffix);
+		return sb.toString();
+	}
+
+	/**
+	 * Return whether the specified string is an annotation.
+	 */
+	private boolean stringIsAnnotation(String string) {
+		return (string.length() > 1) && string.charAt(0) == '@';
+	}
+
+	/**
+	 * If the specified string is a single comma, possibly surrounded by
+	 * spaces, return the length of the substring containing the
+	 * initial spaces and the comma.
+	 */
+	private int commaLength(String string) {
+		boolean comma = false;
+		int len = string.length();
+		int result = 0;
+		for (int i = 0; i < len; i++) {
+			switch (string.charAt(i)) {
+				case ' ' :
+					if ( ! comma) {
+						result++;  // space preceding comma
+					}
+					break;
+				case ',' :
+					if (comma) {
+						return 0;  // second comma!
+					}
+					comma = true;
+					result++;
+					break;
+				default:
+					return 0;  // non-comma, non-space char
+			}
+		}
+		return result;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/jdtutility/NullAnnotationEditFormatter.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/jdtutility/NullAnnotationEditFormatter.java
new file mode 100644
index 0000000..06e831e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/jdtutility/NullAnnotationEditFormatter.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.jdtutility;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+
+public final class NullAnnotationEditFormatter
+	implements AnnotationEditFormatter
+{
+
+	private static NullAnnotationEditFormatter INSTANCE = new NullAnnotationEditFormatter();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static AnnotationEditFormatter instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private NullAnnotationEditFormatter() {
+		super();
+	}
+
+	public void format(IDocument doc, TextEdit editTree) throws MalformedTreeException, BadLocationException {
+		// no formatting
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/BaseJpaFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/BaseJpaFactory.java
new file mode 100644
index 0000000..447456b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/BaseJpaFactory.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0, which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.platform;
+
+import org.eclipse.jpt.core.internal.IJpaFactory;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaBasic;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbeddable;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbedded;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbeddedId;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEntity;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaId;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaManyToMany;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaManyToOne;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaMappedSuperclass;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaOneToMany;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaOneToOne;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaTransient;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaVersion;
+import org.eclipse.jpt.core.internal.content.java.mappings.JpaJavaMappingsFactory;
+import org.eclipse.jpt.core.internal.jdtutility.Attribute;
+import org.eclipse.jpt.core.internal.jdtutility.Type;
+
+public abstract class BaseJpaFactory implements IJpaFactory
+{
+	public IJavaEntity createJavaEntity(Type type) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaEntity(type);
+	}
+	
+	public IJavaEmbeddable createJavaEmbeddable(Type type) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaEmbeddable(type);
+	}
+	
+	public IJavaMappedSuperclass createJavaMappedSuperclass(Type type) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaMappedSuperclass(type);
+	}
+		
+	public IJavaBasic createJavaBasic(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaBasic(attribute);
+	}
+	
+	public IJavaEmbedded createJavaEmbedded(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaEmbedded(attribute);
+	}
+	
+	public IJavaEmbeddedId createJavaEmbeddedId(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaEmbeddedId(attribute);
+	}
+	
+	public IJavaId createJavaId(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaId(attribute);
+	}
+	
+	public IJavaManyToMany createJavaManyToMany(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaManyToMany(attribute);
+	}
+	
+	public IJavaManyToOne createJavaManyToOne(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaManyToOne(attribute);
+	}
+	
+	public IJavaOneToMany createJavaOneToMany(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaOneToMany(attribute);
+	}
+	
+	public IJavaOneToOne createJavaOneToOne(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaOneToOne(attribute);
+	}
+	
+	public IJavaTransient createJavaTransient(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaTransient(attribute);
+	}
+	
+	public IJavaVersion createJavaVersion(Attribute attribute) {
+		return JpaJavaMappingsFactory.eINSTANCE.createJavaVersion(attribute);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/generic/GenericJpaFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/generic/GenericJpaFactory.java
new file mode 100644
index 0000000..31a2594
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/generic/GenericJpaFactory.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0, which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.core.internal.platform.generic;
+
+import org.eclipse.jpt.core.internal.platform.BaseJpaFactory;
+
+public class GenericJpaFactory extends BaseJpaFactory
+{}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/common/translators/BooleanTranslator.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/common/translators/BooleanTranslator.java
new file mode 100644
index 0000000..966e021
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/common/translators/BooleanTranslator.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.resource.common.translators;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+
+public class BooleanTranslator extends Translator
+{
+	public BooleanTranslator(String domNameAndPath, EStructuralFeature aFeature) {
+		super(domNameAndPath, aFeature, BOOLEAN_FEATURE | BOOLEAN_LOWERCASE);
+	}
+	
+	public BooleanTranslator(String domNameAndPath, EStructuralFeature aFeature, int style) {
+		super(domNameAndPath, aFeature, BOOLEAN_FEATURE | BOOLEAN_LOWERCASE | style);
+	}
+		
+	public Object convertStringToValue(String strValue, EObject owner) {
+		return Boolean.valueOf(strValue);
+	}
+	
+	public String convertValueToString(Object value, EObject owner) {
+		return ((Boolean) value).toString();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/JavaClassRef.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/JavaClassRef.java
new file mode 100644
index 0000000..155bde3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/JavaClassRef.java
@@ -0,0 +1,194 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: JavaClassRef.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Java Class Ref</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef#getJavaClass <em>Java Class</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getJavaClassRef()
+ * @model kind="class"
+ * @generated
+ */
+public class JavaClassRef extends EObjectImpl implements EObject
+{
+	/**
+	 * The default value of the '{@link #getJavaClass() <em>Java Class</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getJavaClass()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String JAVA_CLASS_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getJavaClass() <em>Java Class</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getJavaClass()
+	 * @generated
+	 * @ordered
+	 */
+	protected String javaClass = JAVA_CLASS_EDEFAULT;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected JavaClassRef()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass()
+	{
+		return PersistencePackage.Literals.JAVA_CLASS_REF;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Java Class</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Java Class</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Java Class</em>' attribute.
+	 * @see #setJavaClass(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getJavaClassRef_JavaClass()
+	 * @model unique="false" ordered="false"
+	 * @generated
+	 */
+	public String getJavaClass()
+	{
+		return javaClass;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef#getJavaClass <em>Java Class</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Java Class</em>' attribute.
+	 * @see #getJavaClass()
+	 * @generated
+	 */
+	public void setJavaClass(String newJavaClass)
+	{
+		String oldJavaClass = javaClass;
+		javaClass = newJavaClass;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.JAVA_CLASS_REF__JAVA_CLASS, oldJavaClass, javaClass));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.JAVA_CLASS_REF__JAVA_CLASS:
+				return getJavaClass();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eSet(int featureID, Object newValue)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.JAVA_CLASS_REF__JAVA_CLASS:
+				setJavaClass((String)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.JAVA_CLASS_REF__JAVA_CLASS:
+				setJavaClass(JAVA_CLASS_EDEFAULT);
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.JAVA_CLASS_REF__JAVA_CLASS:
+				return JAVA_CLASS_EDEFAULT == null ? javaClass != null : !JAVA_CLASS_EDEFAULT.equals(javaClass);
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString()
+	{
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (javaClass: ");
+		result.append(javaClass);
+		result.append(')');
+		return result.toString();
+	}
+
+} // JavaClassRef
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/MappingFileRef.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/MappingFileRef.java
new file mode 100644
index 0000000..0cdb513
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/MappingFileRef.java
@@ -0,0 +1,195 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: MappingFileRef.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Mapping File Ref</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef#getFileName <em>File Name</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getMappingFileRef()
+ * @model kind="class"
+ * @generated
+ */
+public class MappingFileRef extends EObjectImpl implements EObject
+{
+	/**
+	 * The default value of the '{@link #getFileName() <em>File Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getFileName()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String FILE_NAME_EDEFAULT = "";
+
+	/**
+	 * The cached value of the '{@link #getFileName() <em>File Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getFileName()
+	 * @generated
+	 * @ordered
+	 */
+	protected String fileName = FILE_NAME_EDEFAULT;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected MappingFileRef()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass()
+	{
+		return PersistencePackage.Literals.MAPPING_FILE_REF;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>File Name</b></em>' attribute.
+	 * The default value is <code>""</code>.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>File Name</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>File Name</em>' attribute.
+	 * @see #setFileName(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getMappingFileRef_FileName()
+	 * @model default="" unique="false" ordered="false"
+	 * @generated
+	 */
+	public String getFileName()
+	{
+		return fileName;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef#getFileName <em>File Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>File Name</em>' attribute.
+	 * @see #getFileName()
+	 * @generated
+	 */
+	public void setFileName(String newFileName)
+	{
+		String oldFileName = fileName;
+		fileName = newFileName;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.MAPPING_FILE_REF__FILE_NAME, oldFileName, fileName));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.MAPPING_FILE_REF__FILE_NAME:
+				return getFileName();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eSet(int featureID, Object newValue)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.MAPPING_FILE_REF__FILE_NAME:
+				setFileName((String)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.MAPPING_FILE_REF__FILE_NAME:
+				setFileName(FILE_NAME_EDEFAULT);
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.MAPPING_FILE_REF__FILE_NAME:
+				return FILE_NAME_EDEFAULT == null ? fileName != null : !FILE_NAME_EDEFAULT.equals(fileName);
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString()
+	{
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (fileName: ");
+		result.append(fileName);
+		result.append(')');
+		return result.toString();
+	}
+
+} // MappingFileRef
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Persistence.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Persistence.java
new file mode 100644
index 0000000..65e959b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Persistence.java
@@ -0,0 +1,265 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: Persistence.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Persistence</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence#getPersistenceUnits <em>Persistence Units</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence#getVersion <em>Version</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistence()
+ * @model kind="class"
+ * @generated
+ */
+public class Persistence extends EObjectImpl implements EObject
+{
+	/**
+	 * The cached value of the '{@link #getPersistenceUnits() <em>Persistence Units</em>}' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getPersistenceUnits()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<PersistenceUnit> persistenceUnits;
+
+	/**
+	 * The default value of the '{@link #getVersion() <em>Version</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getVersion()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String VERSION_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getVersion() <em>Version</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getVersion()
+	 * @generated
+	 * @ordered
+	 */
+	protected String version = VERSION_EDEFAULT;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected Persistence()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass()
+	{
+		return PersistencePackage.Literals.PERSISTENCE;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Version</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Version</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Version</em>' attribute.
+	 * @see #setVersion(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistence_Version()
+	 * @model unique="false" dataType="org.eclipse.jpt.core.internal.resource.persistence.Version" required="true"
+	 * @generated
+	 */
+	public String getVersion()
+	{
+		return version;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence#getVersion <em>Version</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Version</em>' attribute.
+	 * @see #getVersion()
+	 * @generated
+	 */
+	public void setVersion(String newVersion)
+	{
+		String oldVersion = version;
+		version = newVersion;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE__VERSION, oldVersion, version));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Persistence Units</b></em>' containment reference list.
+	 * The list contents are of type {@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Persistence Units</em>' containment reference list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Persistence Units</em>' containment reference list.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistence_PersistenceUnits()
+	 * @model containment="true"
+	 * @generated
+	 */
+	public EList<PersistenceUnit> getPersistenceUnits()
+	{
+		if (persistenceUnits == null)
+		{
+			persistenceUnits = new EObjectContainmentEList<PersistenceUnit>(PersistenceUnit.class, this, PersistencePackage.PERSISTENCE__PERSISTENCE_UNITS);
+		}
+		return persistenceUnits;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE__PERSISTENCE_UNITS:
+				return ((InternalEList<?>)getPersistenceUnits()).basicRemove(otherEnd, msgs);
+		}
+		return super.eInverseRemove(otherEnd, featureID, msgs);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE__PERSISTENCE_UNITS:
+				return getPersistenceUnits();
+			case PersistencePackage.PERSISTENCE__VERSION:
+				return getVersion();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void eSet(int featureID, Object newValue)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE__PERSISTENCE_UNITS:
+				getPersistenceUnits().clear();
+				getPersistenceUnits().addAll((Collection<? extends PersistenceUnit>)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE__VERSION:
+				setVersion((String)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE__PERSISTENCE_UNITS:
+				getPersistenceUnits().clear();
+				return;
+			case PersistencePackage.PERSISTENCE__VERSION:
+				setVersion(VERSION_EDEFAULT);
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE__PERSISTENCE_UNITS:
+				return persistenceUnits != null && !persistenceUnits.isEmpty();
+			case PersistencePackage.PERSISTENCE__VERSION:
+				return VERSION_EDEFAULT == null ? version != null : !VERSION_EDEFAULT.equals(version);
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString()
+	{
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (version: ");
+		result.append(version);
+		result.append(')');
+		return result.toString();
+	}
+
+} // Persistence
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceFactory.java
new file mode 100644
index 0000000..fba283f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceFactory.java
@@ -0,0 +1,285 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: PersistenceFactory.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import org.eclipse.emf.common.util.Enumerator;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Factory</b> for the model.
+ * It provides a create method for each non-abstract class of the model.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage
+ * @generated
+ */
+public class PersistenceFactory extends EFactoryImpl
+{
+	/**
+	 * The singleton instance of the factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final PersistenceFactory eINSTANCE = init();
+
+	/**
+	 * Creates the default factory implementation.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static PersistenceFactory init()
+	{
+		try
+		{
+			PersistenceFactory thePersistenceFactory = (PersistenceFactory)EPackage.Registry.INSTANCE.getEFactory("jpt.persistence.xmi"); 
+			if (thePersistenceFactory != null)
+			{
+				return thePersistenceFactory;
+			}
+		}
+		catch (Exception exception)
+		{
+			EcorePlugin.INSTANCE.log(exception);
+		}
+		return new PersistenceFactory();
+	}
+
+	/**
+	 * Creates an instance of the factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public PersistenceFactory()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public EObject create(EClass eClass)
+	{
+		switch (eClass.getClassifierID())
+		{
+			case PersistencePackage.PERSISTENCE: return createPersistence();
+			case PersistencePackage.PERSISTENCE_UNIT: return createPersistenceUnit();
+			case PersistencePackage.MAPPING_FILE_REF: return createMappingFileRef();
+			case PersistencePackage.JAVA_CLASS_REF: return createJavaClassRef();
+			case PersistencePackage.PROPERTIES: return createProperties();
+			case PersistencePackage.PROPERTY: return createProperty();
+			default:
+				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
+		}
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object createFromString(EDataType eDataType, String initialValue)
+	{
+		switch (eDataType.getClassifierID())
+		{
+			case PersistencePackage.PERSISTENCE_UNIT_TRANSACTION_TYPE:
+				return createPersistenceUnitTransactionTypeFromString(eDataType, initialValue);
+			case PersistencePackage.PERSISTENCE_UNIT_TRANSACTION_TYPE_OBJECT:
+				return createPersistenceUnitTransactionTypeObjectFromString(eDataType, initialValue);
+			case PersistencePackage.VERSION:
+				return createVersionFromString(eDataType, initialValue);
+			default:
+				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
+		}
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String convertToString(EDataType eDataType, Object instanceValue)
+	{
+		switch (eDataType.getClassifierID())
+		{
+			case PersistencePackage.PERSISTENCE_UNIT_TRANSACTION_TYPE:
+				return convertPersistenceUnitTransactionTypeToString(eDataType, instanceValue);
+			case PersistencePackage.PERSISTENCE_UNIT_TRANSACTION_TYPE_OBJECT:
+				return convertPersistenceUnitTransactionTypeObjectToString(eDataType, instanceValue);
+			case PersistencePackage.VERSION:
+				return convertVersionToString(eDataType, instanceValue);
+			default:
+				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
+		}
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public Persistence createPersistence()
+	{
+		Persistence persistence = new Persistence();
+		return persistence;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public PersistenceUnit createPersistenceUnit()
+	{
+		PersistenceUnit persistenceUnit = new PersistenceUnit();
+		return persistenceUnit;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public MappingFileRef createMappingFileRef()
+	{
+		MappingFileRef mappingFileRef = new MappingFileRef();
+		return mappingFileRef;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public JavaClassRef createJavaClassRef()
+	{
+		JavaClassRef javaClassRef = new JavaClassRef();
+		return javaClassRef;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public Properties createProperties()
+	{
+		Properties properties = new Properties();
+		return properties;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public Property createProperty()
+	{
+		Property property = new Property();
+		return property;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public PersistenceUnitTransactionType createPersistenceUnitTransactionTypeFromString(EDataType eDataType, String initialValue)
+	{
+		PersistenceUnitTransactionType result = PersistenceUnitTransactionType.get(initialValue);
+		if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'");
+		return result;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String convertPersistenceUnitTransactionTypeToString(EDataType eDataType, Object instanceValue)
+	{
+		return instanceValue == null ? null : instanceValue.toString();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public Enumerator createPersistenceUnitTransactionTypeObjectFromString(EDataType eDataType, String initialValue)
+	{
+		return (Enumerator)super.createFromString(eDataType, initialValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String convertPersistenceUnitTransactionTypeObjectToString(EDataType eDataType, Object instanceValue)
+	{
+		return super.convertToString(eDataType, instanceValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String createVersionFromString(EDataType eDataType, String initialValue)
+	{
+		return (String)super.createFromString(eDataType, initialValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String convertVersionToString(EDataType eDataType, Object instanceValue)
+	{
+		return super.convertToString(eDataType, instanceValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public PersistencePackage getPersistencePackage()
+	{
+		return (PersistencePackage)getEPackage();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @deprecated
+	 * @generated
+	 */
+	@Deprecated
+	public static PersistencePackage getPackage()
+	{
+		return PersistencePackage.eINSTANCE;
+	}
+
+} //PersistenceFactory
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistencePackage.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistencePackage.java
new file mode 100644
index 0000000..50faf95
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistencePackage.java
@@ -0,0 +1,1285 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: PersistencePackage.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import org.eclipse.emf.common.util.Enumerator;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcorePackage;
+
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ *   <li>each class,</li>
+ *   <li>each feature of each class,</li>
+ *   <li>each enum,</li>
+ *   <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceFactory
+ * @model kind="package"
+ * @generated
+ */
+public class PersistencePackage extends EPackageImpl
+{
+	/**
+	 * The package name.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final String eNAME = "persistence";
+
+	/**
+	 * The package namespace URI.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final String eNS_URI = "jpt.persistence.xmi";
+
+	/**
+	 * The package namespace name.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final String eNS_PREFIX = "org.eclipse.jpt.core.resource.persistence";
+
+	/**
+	 * The singleton instance of the package.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final PersistencePackage eINSTANCE = org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage.init();
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence <em>Persistence</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Persistence
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistence()
+	 * @generated
+	 */
+	public static final int PERSISTENCE = 0;
+
+	/**
+	 * The feature id for the '<em><b>Persistence Units</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE__PERSISTENCE_UNITS = 0;
+
+	/**
+	 * The feature id for the '<em><b>Version</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE__VERSION = 1;
+
+	/**
+	 * The number of structural features of the '<em>Persistence</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_FEATURE_COUNT = 2;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit <em>Unit</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit()
+	 * @generated
+	 */
+	public static final int PERSISTENCE_UNIT = 1;
+
+	/**
+	 * The feature id for the '<em><b>Description</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__DESCRIPTION = 0;
+
+	/**
+	 * The feature id for the '<em><b>Provider</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__PROVIDER = 1;
+
+	/**
+	 * The feature id for the '<em><b>Jta Data Source</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__JTA_DATA_SOURCE = 2;
+
+	/**
+	 * The feature id for the '<em><b>Non Jta Data Source</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE = 3;
+
+	/**
+	 * The feature id for the '<em><b>Mapping Files</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__MAPPING_FILES = 4;
+
+	/**
+	 * The feature id for the '<em><b>Jar Files</b></em>' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__JAR_FILES = 5;
+
+	/**
+	 * The feature id for the '<em><b>Classes</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__CLASSES = 6;
+
+	/**
+	 * The feature id for the '<em><b>Exclude Unlisted Classes</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES = 7;
+
+	/**
+	 * The feature id for the '<em><b>Properties</b></em>' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__PROPERTIES = 8;
+
+	/**
+	 * The feature id for the '<em><b>Name</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__NAME = 9;
+
+	/**
+	 * The feature id for the '<em><b>Transaction Type</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT__TRANSACTION_TYPE = 10;
+
+	/**
+	 * The number of structural features of the '<em>Unit</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PERSISTENCE_UNIT_FEATURE_COUNT = 11;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef <em>Mapping File Ref</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getMappingFileRef()
+	 * @generated
+	 */
+	public static final int MAPPING_FILE_REF = 2;
+
+	/**
+	 * The feature id for the '<em><b>File Name</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int MAPPING_FILE_REF__FILE_NAME = 0;
+
+	/**
+	 * The number of structural features of the '<em>Mapping File Ref</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int MAPPING_FILE_REF_FEATURE_COUNT = 1;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef <em>Java Class Ref</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getJavaClassRef()
+	 * @generated
+	 */
+	public static final int JAVA_CLASS_REF = 3;
+
+	/**
+	 * The feature id for the '<em><b>Java Class</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int JAVA_CLASS_REF__JAVA_CLASS = 0;
+
+	/**
+	 * The number of structural features of the '<em>Java Class Ref</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int JAVA_CLASS_REF_FEATURE_COUNT = 1;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.Properties <em>Properties</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Properties
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperties()
+	 * @generated
+	 */
+	public static final int PROPERTIES = 4;
+
+	/**
+	 * The feature id for the '<em><b>Properties</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PROPERTIES__PROPERTIES = 0;
+
+	/**
+	 * The number of structural features of the '<em>Properties</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PROPERTIES_FEATURE_COUNT = 1;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.Property <em>Property</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Property
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperty()
+	 * @generated
+	 */
+	public static final int PROPERTY = 5;
+
+	/**
+	 * The feature id for the '<em><b>Name</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PROPERTY__NAME = 0;
+
+	/**
+	 * The feature id for the '<em><b>Value</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PROPERTY__VALUE = 1;
+
+	/**
+	 * The number of structural features of the '<em>Property</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int PROPERTY_FEATURE_COUNT = 2;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType <em>Unit Transaction Type</em>}' enum.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnitTransactionType()
+	 * @generated
+	 */
+	public static final int PERSISTENCE_UNIT_TRANSACTION_TYPE = 6;
+
+	/**
+	 * The meta object id for the '<em>Unit Transaction Type Object</em>' data type.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.emf.common.util.Enumerator
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnitTransactionTypeObject()
+	 * @generated
+	 */
+	public static final int PERSISTENCE_UNIT_TRANSACTION_TYPE_OBJECT = 7;
+
+	/**
+	 * The meta object id for the '<em>Version</em>' data type.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see java.lang.String
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getVersion()
+	 * @generated
+	 */
+	public static final int VERSION = 8;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass persistenceEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass persistenceUnitEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass mappingFileRefEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass javaClassRefEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass propertiesEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass propertyEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EEnum persistenceUnitTransactionTypeEEnum = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EDataType persistenceUnitTransactionTypeObjectEDataType = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EDataType versionEDataType = null;
+
+	/**
+	 * Creates an instance of the model <b>Package</b>, registered with
+	 * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
+	 * package URI value.
+	 * <p>Note: the correct way to create the package is via the static
+	 * factory method {@link #init init()}, which also performs
+	 * initialization of the package, or returns the registered package,
+	 * if one already exists.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.emf.ecore.EPackage.Registry
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#eNS_URI
+	 * @see #init()
+	 * @generated
+	 */
+	private PersistencePackage()
+	{
+		super(eNS_URI, PersistenceFactory.eINSTANCE);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private static boolean isInited = false;
+
+	/**
+	 * Creates, registers, and initializes the <b>Package</b> for this
+	 * model, and for any others upon which it depends.  Simple
+	 * dependencies are satisfied by calling this method on all
+	 * dependent packages before doing anything else.  This method drives
+	 * initialization for interdependent packages directly, in parallel
+	 * with this package, itself.
+	 * <p>Of this package and its interdependencies, all packages which
+	 * have not yet been registered by their URI values are first created
+	 * and registered.  The packages are then initialized in two steps:
+	 * meta-model objects for all of the packages are created before any
+	 * are initialized, since one package's meta-model objects may refer to
+	 * those of another.
+	 * <p>Invocation of this method will not affect any packages that have
+	 * already been initialized.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #eNS_URI
+	 * @see #createPackageContents()
+	 * @see #initializePackageContents()
+	 * @generated
+	 */
+	public static PersistencePackage init()
+	{
+		if (isInited) return (PersistencePackage)EPackage.Registry.INSTANCE.getEPackage(PersistencePackage.eNS_URI);
+
+		// Obtain or create and register package
+		PersistencePackage thePersistencePackage = (PersistencePackage)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof PersistencePackage ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new PersistencePackage());
+
+		isInited = true;
+
+		// Initialize simple dependencies
+		EcorePackage.eINSTANCE.eClass();
+		XMLTypePackage.eINSTANCE.eClass();
+
+		// Create package meta-data objects
+		thePersistencePackage.createPackageContents();
+
+		// Initialize created meta-data
+		thePersistencePackage.initializePackageContents();
+
+		// Mark meta-data to indicate it can't be changed
+		thePersistencePackage.freeze();
+
+		return thePersistencePackage;
+	}
+
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence <em>Persistence</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Persistence</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Persistence
+	 * @generated
+	 */
+	public EClass getPersistence()
+	{
+		return persistenceEClass;
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence#getVersion <em>Version</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Version</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Persistence#getVersion()
+	 * @see #getPersistence()
+	 * @generated
+	 */
+	public EAttribute getPersistence_Version()
+	{
+		return (EAttribute)persistenceEClass.getEStructuralFeatures().get(1);
+	}
+
+	/**
+	 * Returns the meta object for the containment reference list '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence#getPersistenceUnits <em>Persistence Units</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference list '<em>Persistence Units</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Persistence#getPersistenceUnits()
+	 * @see #getPersistence()
+	 * @generated
+	 */
+	public EReference getPersistence_PersistenceUnits()
+	{
+		return (EReference)persistenceEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit <em>Unit</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Unit</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit
+	 * @generated
+	 */
+	public EClass getPersistenceUnit()
+	{
+		return persistenceUnitEClass;
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getName <em>Name</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Name</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getName()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_Name()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(9);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getTransactionType <em>Transaction Type</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Transaction Type</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getTransactionType()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_TransactionType()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(10);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getDescription <em>Description</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Description</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getDescription()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_Description()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProvider <em>Provider</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Provider</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProvider()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_Provider()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(1);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJtaDataSource <em>Jta Data Source</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Jta Data Source</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJtaDataSource()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_JtaDataSource()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(2);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getNonJtaDataSource <em>Non Jta Data Source</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Non Jta Data Source</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getNonJtaDataSource()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_NonJtaDataSource()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(3);
+	}
+
+	/**
+	 * Returns the meta object for the containment reference list '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getMappingFiles <em>Mapping Files</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference list '<em>Mapping Files</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getMappingFiles()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EReference getPersistenceUnit_MappingFiles()
+	{
+		return (EReference)persistenceUnitEClass.getEStructuralFeatures().get(4);
+	}
+
+	/**
+	 * Returns the meta object for the attribute list '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJarFiles <em>Jar Files</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute list '<em>Jar Files</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJarFiles()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_JarFiles()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(5);
+	}
+
+	/**
+	 * Returns the meta object for the containment reference list '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getClasses <em>Classes</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference list '<em>Classes</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getClasses()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EReference getPersistenceUnit_Classes()
+	{
+		return (EReference)persistenceUnitEClass.getEStructuralFeatures().get(6);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#isExcludeUnlistedClasses <em>Exclude Unlisted Classes</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Exclude Unlisted Classes</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#isExcludeUnlistedClasses()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EAttribute getPersistenceUnit_ExcludeUnlistedClasses()
+	{
+		return (EAttribute)persistenceUnitEClass.getEStructuralFeatures().get(7);
+	}
+
+	/**
+	 * Returns the meta object for the containment reference '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProperties <em>Properties</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference '<em>Properties</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProperties()
+	 * @see #getPersistenceUnit()
+	 * @generated
+	 */
+	public EReference getPersistenceUnit_Properties()
+	{
+		return (EReference)persistenceUnitEClass.getEStructuralFeatures().get(8);
+	}
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef <em>Mapping File Ref</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Mapping File Ref</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef
+	 * @generated
+	 */
+	public EClass getMappingFileRef()
+	{
+		return mappingFileRefEClass;
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef#getFileName <em>File Name</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>File Name</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef#getFileName()
+	 * @see #getMappingFileRef()
+	 * @generated
+	 */
+	public EAttribute getMappingFileRef_FileName()
+	{
+		return (EAttribute)mappingFileRefEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef <em>Java Class Ref</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Java Class Ref</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef
+	 * @generated
+	 */
+	public EClass getJavaClassRef()
+	{
+		return javaClassRefEClass;
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef#getJavaClass <em>Java Class</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Java Class</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef#getJavaClass()
+	 * @see #getJavaClassRef()
+	 * @generated
+	 */
+	public EAttribute getJavaClassRef_JavaClass()
+	{
+		return (EAttribute)javaClassRefEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.jpt.core.internal.resource.persistence.Properties <em>Properties</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Properties</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Properties
+	 * @generated
+	 */
+	public EClass getProperties()
+	{
+		return propertiesEClass;
+	}
+
+	/**
+	 * Returns the meta object for the containment reference list '{@link org.eclipse.jpt.core.internal.resource.persistence.Properties#getProperties <em>Properties</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference list '<em>Properties</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Properties#getProperties()
+	 * @see #getProperties()
+	 * @generated
+	 */
+	public EReference getProperties_Properties()
+	{
+		return (EReference)propertiesEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.jpt.core.internal.resource.persistence.Property <em>Property</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Property</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Property
+	 * @generated
+	 */
+	public EClass getProperty()
+	{
+		return propertyEClass;
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.Property#getName <em>Name</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Name</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Property#getName()
+	 * @see #getProperty()
+	 * @generated
+	 */
+	public EAttribute getProperty_Name()
+	{
+		return (EAttribute)propertyEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.jpt.core.internal.resource.persistence.Property#getValue <em>Value</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Value</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Property#getValue()
+	 * @see #getProperty()
+	 * @generated
+	 */
+	public EAttribute getProperty_Value()
+	{
+		return (EAttribute)propertyEClass.getEStructuralFeatures().get(1);
+	}
+
+	/**
+	 * Returns the meta object for enum '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType <em>Unit Transaction Type</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for enum '<em>Unit Transaction Type</em>'.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType
+	 * @generated
+	 */
+	public EEnum getPersistenceUnitTransactionType()
+	{
+		return persistenceUnitTransactionTypeEEnum;
+	}
+
+	/**
+	 * Returns the meta object for data type '{@link org.eclipse.emf.common.util.Enumerator <em>Unit Transaction Type Object</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for data type '<em>Unit Transaction Type Object</em>'.
+	 * @see org.eclipse.emf.common.util.Enumerator
+	 * @model instanceClass="org.eclipse.emf.common.util.Enumerator"
+	 * @generated
+	 */
+	public EDataType getPersistenceUnitTransactionTypeObject()
+	{
+		return persistenceUnitTransactionTypeObjectEDataType;
+	}
+
+	/**
+	 * Returns the meta object for data type '{@link java.lang.String <em>Version</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for data type '<em>Version</em>'.
+	 * @see java.lang.String
+	 * @model instanceClass="java.lang.String"
+	 * @generated
+	 */
+	public EDataType getVersion()
+	{
+		return versionEDataType;
+	}
+
+	/**
+	 * Returns the factory that creates the instances of the model.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the factory that creates the instances of the model.
+	 * @generated
+	 */
+	public PersistenceFactory getPersistenceFactory()
+	{
+		return (PersistenceFactory)getEFactoryInstance();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private boolean isCreated = false;
+
+	/**
+	 * Creates the meta-model objects for the package.  This method is
+	 * guarded to have no affect on any invocation but its first.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void createPackageContents()
+	{
+		if (isCreated) return;
+		isCreated = true;
+
+		// Create classes and their features
+		persistenceEClass = createEClass(PERSISTENCE);
+		createEReference(persistenceEClass, PERSISTENCE__PERSISTENCE_UNITS);
+		createEAttribute(persistenceEClass, PERSISTENCE__VERSION);
+
+		persistenceUnitEClass = createEClass(PERSISTENCE_UNIT);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__DESCRIPTION);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__PROVIDER);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__JTA_DATA_SOURCE);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE);
+		createEReference(persistenceUnitEClass, PERSISTENCE_UNIT__MAPPING_FILES);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__JAR_FILES);
+		createEReference(persistenceUnitEClass, PERSISTENCE_UNIT__CLASSES);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES);
+		createEReference(persistenceUnitEClass, PERSISTENCE_UNIT__PROPERTIES);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__NAME);
+		createEAttribute(persistenceUnitEClass, PERSISTENCE_UNIT__TRANSACTION_TYPE);
+
+		mappingFileRefEClass = createEClass(MAPPING_FILE_REF);
+		createEAttribute(mappingFileRefEClass, MAPPING_FILE_REF__FILE_NAME);
+
+		javaClassRefEClass = createEClass(JAVA_CLASS_REF);
+		createEAttribute(javaClassRefEClass, JAVA_CLASS_REF__JAVA_CLASS);
+
+		propertiesEClass = createEClass(PROPERTIES);
+		createEReference(propertiesEClass, PROPERTIES__PROPERTIES);
+
+		propertyEClass = createEClass(PROPERTY);
+		createEAttribute(propertyEClass, PROPERTY__NAME);
+		createEAttribute(propertyEClass, PROPERTY__VALUE);
+
+		// Create enums
+		persistenceUnitTransactionTypeEEnum = createEEnum(PERSISTENCE_UNIT_TRANSACTION_TYPE);
+
+		// Create data types
+		persistenceUnitTransactionTypeObjectEDataType = createEDataType(PERSISTENCE_UNIT_TRANSACTION_TYPE_OBJECT);
+		versionEDataType = createEDataType(VERSION);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private boolean isInitialized = false;
+
+	/**
+	 * Complete the initialization of the package and its meta-model.  This
+	 * method is guarded to have no affect on any invocation but its first.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void initializePackageContents()
+	{
+		if (isInitialized) return;
+		isInitialized = true;
+
+		// Initialize package
+		setName(eNAME);
+		setNsPrefix(eNS_PREFIX);
+		setNsURI(eNS_URI);
+
+		// Obtain other dependent packages
+		XMLTypePackage theXMLTypePackage = (XMLTypePackage)EPackage.Registry.INSTANCE.getEPackage(XMLTypePackage.eNS_URI);
+		EcorePackage theEcorePackage = (EcorePackage)EPackage.Registry.INSTANCE.getEPackage(EcorePackage.eNS_URI);
+
+		// Create type parameters
+
+		// Set bounds for type parameters
+
+		// Add supertypes to classes
+
+		// Initialize classes and features; add operations and parameters
+		initEClass(persistenceEClass, Persistence.class, "Persistence", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEReference(getPersistence_PersistenceUnits(), this.getPersistenceUnit(), null, "persistenceUnits", null, 0, -1, Persistence.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistence_Version(), this.getVersion(), "version", null, 1, 1, Persistence.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+		initEClass(persistenceUnitEClass, PersistenceUnit.class, "PersistenceUnit", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEAttribute(getPersistenceUnit_Description(), theXMLTypePackage.getString(), "description", null, 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_Provider(), theXMLTypePackage.getString(), "provider", null, 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_JtaDataSource(), theXMLTypePackage.getString(), "jtaDataSource", null, 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_NonJtaDataSource(), theXMLTypePackage.getString(), "nonJtaDataSource", null, 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEReference(getPersistenceUnit_MappingFiles(), this.getMappingFileRef(), null, "mappingFiles", null, 0, -1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_JarFiles(), theXMLTypePackage.getString(), "jarFiles", null, 0, -1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEReference(getPersistenceUnit_Classes(), this.getJavaClassRef(), null, "classes", null, 0, -1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_ExcludeUnlistedClasses(), theXMLTypePackage.getBoolean(), "excludeUnlistedClasses", "false", 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEReference(getPersistenceUnit_Properties(), this.getProperties(), null, "properties", null, 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_Name(), theXMLTypePackage.getString(), "name", null, 1, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getPersistenceUnit_TransactionType(), this.getPersistenceUnitTransactionType(), "transactionType", "JTA", 0, 1, PersistenceUnit.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+		initEClass(mappingFileRefEClass, MappingFileRef.class, "MappingFileRef", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEAttribute(getMappingFileRef_FileName(), theEcorePackage.getEString(), "fileName", "", 0, 1, MappingFileRef.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, !IS_ORDERED);
+
+		initEClass(javaClassRefEClass, JavaClassRef.class, "JavaClassRef", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEAttribute(getJavaClassRef_JavaClass(), theEcorePackage.getEString(), "javaClass", null, 0, 1, JavaClassRef.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, !IS_ORDERED);
+
+		initEClass(propertiesEClass, Properties.class, "Properties", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEReference(getProperties_Properties(), this.getProperty(), null, "properties", null, 0, -1, Properties.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+		initEClass(propertyEClass, Property.class, "Property", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEAttribute(getProperty_Name(), theXMLTypePackage.getString(), "name", null, 1, 1, Property.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getProperty_Value(), theXMLTypePackage.getString(), "value", null, 1, 1, Property.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, !IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+		// Initialize enums and add enum literals
+		initEEnum(persistenceUnitTransactionTypeEEnum, PersistenceUnitTransactionType.class, "PersistenceUnitTransactionType");
+		addEEnumLiteral(persistenceUnitTransactionTypeEEnum, PersistenceUnitTransactionType.JTA);
+		addEEnumLiteral(persistenceUnitTransactionTypeEEnum, PersistenceUnitTransactionType.RESOURCE_LOCAL);
+
+		// Initialize data types
+		initEDataType(persistenceUnitTransactionTypeObjectEDataType, Enumerator.class, "PersistenceUnitTransactionTypeObject", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
+		initEDataType(versionEDataType, String.class, "Version", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS);
+
+		// Create resource
+		createResource(eNS_URI);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * Defines literals for the meta objects that represent
+	 * <ul>
+	 *   <li>each class,</li>
+	 *   <li>each feature of each class,</li>
+	 *   <li>each enum,</li>
+	 *   <li>and each data type</li>
+	 * </ul>
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public interface Literals
+	{
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence <em>Persistence</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.Persistence
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistence()
+		 * @generated
+		 */
+		public static final EClass PERSISTENCE = eINSTANCE.getPersistence();
+
+		/**
+		 * The meta object literal for the '<em><b>Version</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE__VERSION = eINSTANCE.getPersistence_Version();
+
+		/**
+		 * The meta object literal for the '<em><b>Persistence Units</b></em>' containment reference list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EReference PERSISTENCE__PERSISTENCE_UNITS = eINSTANCE.getPersistence_PersistenceUnits();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit <em>Unit</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit()
+		 * @generated
+		 */
+		public static final EClass PERSISTENCE_UNIT = eINSTANCE.getPersistenceUnit();
+
+		/**
+		 * The meta object literal for the '<em><b>Name</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__NAME = eINSTANCE.getPersistenceUnit_Name();
+
+		/**
+		 * The meta object literal for the '<em><b>Transaction Type</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__TRANSACTION_TYPE = eINSTANCE.getPersistenceUnit_TransactionType();
+
+		/**
+		 * The meta object literal for the '<em><b>Description</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__DESCRIPTION = eINSTANCE.getPersistenceUnit_Description();
+
+		/**
+		 * The meta object literal for the '<em><b>Provider</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__PROVIDER = eINSTANCE.getPersistenceUnit_Provider();
+
+		/**
+		 * The meta object literal for the '<em><b>Jta Data Source</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__JTA_DATA_SOURCE = eINSTANCE.getPersistenceUnit_JtaDataSource();
+
+		/**
+		 * The meta object literal for the '<em><b>Non Jta Data Source</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE = eINSTANCE.getPersistenceUnit_NonJtaDataSource();
+
+		/**
+		 * The meta object literal for the '<em><b>Mapping Files</b></em>' containment reference list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EReference PERSISTENCE_UNIT__MAPPING_FILES = eINSTANCE.getPersistenceUnit_MappingFiles();
+
+		/**
+		 * The meta object literal for the '<em><b>Jar Files</b></em>' attribute list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__JAR_FILES = eINSTANCE.getPersistenceUnit_JarFiles();
+
+		/**
+		 * The meta object literal for the '<em><b>Classes</b></em>' containment reference list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EReference PERSISTENCE_UNIT__CLASSES = eINSTANCE.getPersistenceUnit_Classes();
+
+		/**
+		 * The meta object literal for the '<em><b>Exclude Unlisted Classes</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES = eINSTANCE.getPersistenceUnit_ExcludeUnlistedClasses();
+
+		/**
+		 * The meta object literal for the '<em><b>Properties</b></em>' containment reference feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EReference PERSISTENCE_UNIT__PROPERTIES = eINSTANCE.getPersistenceUnit_Properties();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef <em>Mapping File Ref</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getMappingFileRef()
+		 * @generated
+		 */
+		public static final EClass MAPPING_FILE_REF = eINSTANCE.getMappingFileRef();
+
+		/**
+		 * The meta object literal for the '<em><b>File Name</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute MAPPING_FILE_REF__FILE_NAME = eINSTANCE.getMappingFileRef_FileName();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef <em>Java Class Ref</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getJavaClassRef()
+		 * @generated
+		 */
+		public static final EClass JAVA_CLASS_REF = eINSTANCE.getJavaClassRef();
+
+		/**
+		 * The meta object literal for the '<em><b>Java Class</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute JAVA_CLASS_REF__JAVA_CLASS = eINSTANCE.getJavaClassRef_JavaClass();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.Properties <em>Properties</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.Properties
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperties()
+		 * @generated
+		 */
+		public static final EClass PROPERTIES = eINSTANCE.getProperties();
+
+		/**
+		 * The meta object literal for the '<em><b>Properties</b></em>' containment reference list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EReference PROPERTIES__PROPERTIES = eINSTANCE.getProperties_Properties();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.Property <em>Property</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.Property
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperty()
+		 * @generated
+		 */
+		public static final EClass PROPERTY = eINSTANCE.getProperty();
+
+		/**
+		 * The meta object literal for the '<em><b>Name</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PROPERTY__NAME = eINSTANCE.getProperty_Name();
+
+		/**
+		 * The meta object literal for the '<em><b>Value</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute PROPERTY__VALUE = eINSTANCE.getProperty_Value();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType <em>Unit Transaction Type</em>}' enum.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnitTransactionType()
+		 * @generated
+		 */
+		public static final EEnum PERSISTENCE_UNIT_TRANSACTION_TYPE = eINSTANCE.getPersistenceUnitTransactionType();
+
+		/**
+		 * The meta object literal for the '<em>Unit Transaction Type Object</em>' data type.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.emf.common.util.Enumerator
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnitTransactionTypeObject()
+		 * @generated
+		 */
+		public static final EDataType PERSISTENCE_UNIT_TRANSACTION_TYPE_OBJECT = eINSTANCE.getPersistenceUnitTransactionTypeObject();
+
+		/**
+		 * The meta object literal for the '<em>Version</em>' data type.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see java.lang.String
+		 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getVersion()
+		 * @generated
+		 */
+		public static final EDataType VERSION = eINSTANCE.getVersion();
+
+	}
+
+} //PersistencePackage
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceResource.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceResource.java
new file mode 100644
index 0000000..a7b03da
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceResource.java
@@ -0,0 +1,66 @@
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jpt.core.internal.resource.persistence.translators.PersistenceTranslator;
+import org.eclipse.wst.common.internal.emf.resource.Renderer;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
+import org.eclipse.wst.common.internal.emf.resource.TranslatorResourceImpl;
+
+public class PersistenceResource extends TranslatorResourceImpl
+{
+	public PersistenceResource(Renderer aRenderer) {
+		super(aRenderer);
+	}
+
+	public PersistenceResource(URI uri, Renderer aRenderer) {
+		super(uri, aRenderer);
+	}
+	
+	/**
+	 * @see TranslatorResourceImpl#getDefaultPublicId() 
+	 */
+	protected String getDefaultPublicId() {
+		return null;
+		// only applicable for DTD-based files
+	}
+	
+	/**
+	 * @see TranslatorResourceImpl#getDefaultSystemId() 
+	 */
+	protected String getDefaultSystemId() {
+		return null;
+		// only applicable for DTD-based files
+	}
+	
+	/**
+	 * @see TranslatorResourceImpl#getDefaultVersionId() 
+	 */
+	protected int getDefaultVersionID() {
+		return 10;
+		// this seems to be the default version of the spec for this doc
+		// and the id 10 maps to the version 1.0
+	}
+	
+	/**
+	 * @see TranslatorResource#getDoctype() 
+	 */
+	public String getDoctype() {
+		return null;
+		// only applicable for DTD-based files
+	}
+	
+	/**
+	 * @see TranslatorResource#getRootTranslator() 
+	 */
+	public Translator getRootTranslator() {
+		return PersistenceTranslator.INSTANCE;
+	}
+	
+	/**
+	 * @see PersistenceResource#getPersistence()
+	 */
+	public Persistence getPersistence() {
+		return (Persistence) getRootObject();
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceUnit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceUnit.java
new file mode 100644
index 0000000..6ea871d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceUnit.java
@@ -0,0 +1,954 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: PersistenceUnit.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+import org.eclipse.emf.ecore.util.EDataTypeEList;
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Unit</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getDescription <em>Description</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProvider <em>Provider</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJtaDataSource <em>Jta Data Source</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getNonJtaDataSource <em>Non Jta Data Source</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getMappingFiles <em>Mapping Files</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJarFiles <em>Jar Files</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getClasses <em>Classes</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#isExcludeUnlistedClasses <em>Exclude Unlisted Classes</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProperties <em>Properties</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getName <em>Name</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getTransactionType <em>Transaction Type</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit()
+ * @model kind="class"
+ * @generated
+ */
+public class PersistenceUnit extends EObjectImpl implements EObject
+{
+	/**
+	 * The default value of the '{@link #getDescription() <em>Description</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getDescription()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String DESCRIPTION_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getDescription() <em>Description</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getDescription()
+	 * @generated
+	 * @ordered
+	 */
+	protected String description = DESCRIPTION_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getProvider() <em>Provider</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getProvider()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String PROVIDER_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getProvider() <em>Provider</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getProvider()
+	 * @generated
+	 * @ordered
+	 */
+	protected String provider = PROVIDER_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getJtaDataSource() <em>Jta Data Source</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getJtaDataSource()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String JTA_DATA_SOURCE_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getJtaDataSource() <em>Jta Data Source</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getJtaDataSource()
+	 * @generated
+	 * @ordered
+	 */
+	protected String jtaDataSource = JTA_DATA_SOURCE_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getNonJtaDataSource() <em>Non Jta Data Source</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getNonJtaDataSource()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String NON_JTA_DATA_SOURCE_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getNonJtaDataSource() <em>Non Jta Data Source</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getNonJtaDataSource()
+	 * @generated
+	 * @ordered
+	 */
+	protected String nonJtaDataSource = NON_JTA_DATA_SOURCE_EDEFAULT;
+
+	/**
+	 * The cached value of the '{@link #getMappingFiles() <em>Mapping Files</em>}' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getMappingFiles()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<MappingFileRef> mappingFiles;
+
+	/**
+	 * The cached value of the '{@link #getJarFiles() <em>Jar Files</em>}' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getJarFiles()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<String> jarFiles;
+
+	/**
+	 * The cached value of the '{@link #getClasses() <em>Classes</em>}' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getClasses()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<JavaClassRef> classes;
+
+	/**
+	 * The default value of the '{@link #isExcludeUnlistedClasses() <em>Exclude Unlisted Classes</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #isExcludeUnlistedClasses()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final boolean EXCLUDE_UNLISTED_CLASSES_EDEFAULT = false;
+
+	/**
+	 * The cached value of the '{@link #isExcludeUnlistedClasses() <em>Exclude Unlisted Classes</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #isExcludeUnlistedClasses()
+	 * @generated
+	 * @ordered
+	 */
+	protected boolean excludeUnlistedClasses = EXCLUDE_UNLISTED_CLASSES_EDEFAULT;
+
+	/**
+	 * This is true if the Exclude Unlisted Classes attribute has been set.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	protected boolean excludeUnlistedClassesESet;
+
+	/**
+	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getProperties()
+	 * @generated
+	 * @ordered
+	 */
+	protected Properties properties;
+
+	/**
+	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getName()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String NAME_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getName()
+	 * @generated
+	 * @ordered
+	 */
+	protected String name = NAME_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getTransactionType() <em>Transaction Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getTransactionType()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final PersistenceUnitTransactionType TRANSACTION_TYPE_EDEFAULT = PersistenceUnitTransactionType.JTA;
+
+	/**
+	 * The cached value of the '{@link #getTransactionType() <em>Transaction Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getTransactionType()
+	 * @generated
+	 * @ordered
+	 */
+	protected PersistenceUnitTransactionType transactionType = TRANSACTION_TYPE_EDEFAULT;
+
+	/**
+	 * This is true if the Transaction Type attribute has been set.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	protected boolean transactionTypeESet;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected PersistenceUnit()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass()
+	{
+		return PersistencePackage.Literals.PERSISTENCE_UNIT;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Name</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Name</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Name</em>' attribute.
+	 * @see #setName(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_Name()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String" required="true"
+	 * @generated
+	 */
+	public String getName()
+	{
+		return name;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getName <em>Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Name</em>' attribute.
+	 * @see #getName()
+	 * @generated
+	 */
+	public void setName(String newName)
+	{
+		String oldName = name;
+		name = newName;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__NAME, oldName, name));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Transaction Type</b></em>' attribute.
+	 * The default value is <code>"JTA"</code>.
+	 * The literals are from the enumeration {@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Transaction Type</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Transaction Type</em>' attribute.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType
+	 * @see #isSetTransactionType()
+	 * @see #unsetTransactionType()
+	 * @see #setTransactionType(PersistenceUnitTransactionType)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_TransactionType()
+	 * @model default="JTA" unique="false" unsettable="true"
+	 * @generated
+	 */
+	public PersistenceUnitTransactionType getTransactionType()
+	{
+		return transactionType;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getTransactionType <em>Transaction Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Transaction Type</em>' attribute.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType
+	 * @see #isSetTransactionType()
+	 * @see #unsetTransactionType()
+	 * @see #getTransactionType()
+	 * @generated
+	 */
+	public void setTransactionType(PersistenceUnitTransactionType newTransactionType)
+	{
+		PersistenceUnitTransactionType oldTransactionType = transactionType;
+		transactionType = newTransactionType == null ? TRANSACTION_TYPE_EDEFAULT : newTransactionType;
+		boolean oldTransactionTypeESet = transactionTypeESet;
+		transactionTypeESet = true;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__TRANSACTION_TYPE, oldTransactionType, transactionType, !oldTransactionTypeESet));
+	}
+
+	/**
+	 * Unsets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getTransactionType <em>Transaction Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #isSetTransactionType()
+	 * @see #getTransactionType()
+	 * @see #setTransactionType(PersistenceUnitTransactionType)
+	 * @generated
+	 */
+	public void unsetTransactionType()
+	{
+		PersistenceUnitTransactionType oldTransactionType = transactionType;
+		boolean oldTransactionTypeESet = transactionTypeESet;
+		transactionType = TRANSACTION_TYPE_EDEFAULT;
+		transactionTypeESet = false;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.UNSET, PersistencePackage.PERSISTENCE_UNIT__TRANSACTION_TYPE, oldTransactionType, TRANSACTION_TYPE_EDEFAULT, oldTransactionTypeESet));
+	}
+
+	/**
+	 * Returns whether the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getTransactionType <em>Transaction Type</em>}' attribute is set.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return whether the value of the '<em>Transaction Type</em>' attribute is set.
+	 * @see #unsetTransactionType()
+	 * @see #getTransactionType()
+	 * @see #setTransactionType(PersistenceUnitTransactionType)
+	 * @generated
+	 */
+	public boolean isSetTransactionType()
+	{
+		return transactionTypeESet;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Description</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Description</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Description</em>' attribute.
+	 * @see #setDescription(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_Description()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String"
+	 * @generated
+	 */
+	public String getDescription()
+	{
+		return description;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getDescription <em>Description</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Description</em>' attribute.
+	 * @see #getDescription()
+	 * @generated
+	 */
+	public void setDescription(String newDescription)
+	{
+		String oldDescription = description;
+		description = newDescription;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__DESCRIPTION, oldDescription, description));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Provider</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Provider</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Provider</em>' attribute.
+	 * @see #setProvider(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_Provider()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String"
+	 * @generated
+	 */
+	public String getProvider()
+	{
+		return provider;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProvider <em>Provider</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Provider</em>' attribute.
+	 * @see #getProvider()
+	 * @generated
+	 */
+	public void setProvider(String newProvider)
+	{
+		String oldProvider = provider;
+		provider = newProvider;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__PROVIDER, oldProvider, provider));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Jta Data Source</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Jta Data Source</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Jta Data Source</em>' attribute.
+	 * @see #setJtaDataSource(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_JtaDataSource()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String"
+	 * @generated
+	 */
+	public String getJtaDataSource()
+	{
+		return jtaDataSource;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getJtaDataSource <em>Jta Data Source</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Jta Data Source</em>' attribute.
+	 * @see #getJtaDataSource()
+	 * @generated
+	 */
+	public void setJtaDataSource(String newJtaDataSource)
+	{
+		String oldJtaDataSource = jtaDataSource;
+		jtaDataSource = newJtaDataSource;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__JTA_DATA_SOURCE, oldJtaDataSource, jtaDataSource));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Non Jta Data Source</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Non Jta Data Source</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Non Jta Data Source</em>' attribute.
+	 * @see #setNonJtaDataSource(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_NonJtaDataSource()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String"
+	 * @generated
+	 */
+	public String getNonJtaDataSource()
+	{
+		return nonJtaDataSource;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getNonJtaDataSource <em>Non Jta Data Source</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Non Jta Data Source</em>' attribute.
+	 * @see #getNonJtaDataSource()
+	 * @generated
+	 */
+	public void setNonJtaDataSource(String newNonJtaDataSource)
+	{
+		String oldNonJtaDataSource = nonJtaDataSource;
+		nonJtaDataSource = newNonJtaDataSource;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE, oldNonJtaDataSource, nonJtaDataSource));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Mapping Files</b></em>' containment reference list.
+	 * The list contents are of type {@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Mapping Files</em>' containment reference list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Mapping Files</em>' containment reference list.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_MappingFiles()
+	 * @model containment="true"
+	 * @generated
+	 */
+	public EList<MappingFileRef> getMappingFiles()
+	{
+		if (mappingFiles == null)
+		{
+			mappingFiles = new EObjectContainmentEList<MappingFileRef>(MappingFileRef.class, this, PersistencePackage.PERSISTENCE_UNIT__MAPPING_FILES);
+		}
+		return mappingFiles;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Jar Files</b></em>' attribute list.
+	 * The list contents are of type {@link java.lang.String}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Jar Files</em>' attribute list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Jar Files</em>' attribute list.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_JarFiles()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String"
+	 * @generated
+	 */
+	public EList<String> getJarFiles()
+	{
+		if (jarFiles == null)
+		{
+			jarFiles = new EDataTypeEList<String>(String.class, this, PersistencePackage.PERSISTENCE_UNIT__JAR_FILES);
+		}
+		return jarFiles;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Classes</b></em>' containment reference list.
+	 * The list contents are of type {@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Classes</em>' containment reference list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Classes</em>' containment reference list.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_Classes()
+	 * @model containment="true"
+	 * @generated
+	 */
+	public EList<JavaClassRef> getClasses()
+	{
+		if (classes == null)
+		{
+			classes = new EObjectContainmentEList<JavaClassRef>(JavaClassRef.class, this, PersistencePackage.PERSISTENCE_UNIT__CLASSES);
+		}
+		return classes;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Exclude Unlisted Classes</b></em>' attribute.
+	 * The default value is <code>"false"</code>.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Exclude Unlisted Classes</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Exclude Unlisted Classes</em>' attribute.
+	 * @see #isSetExcludeUnlistedClasses()
+	 * @see #unsetExcludeUnlistedClasses()
+	 * @see #setExcludeUnlistedClasses(boolean)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_ExcludeUnlistedClasses()
+	 * @model default="false" unique="false" unsettable="true" dataType="org.eclipse.emf.ecore.xml.type.Boolean"
+	 * @generated
+	 */
+	public boolean isExcludeUnlistedClasses()
+	{
+		return excludeUnlistedClasses;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#isExcludeUnlistedClasses <em>Exclude Unlisted Classes</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Exclude Unlisted Classes</em>' attribute.
+	 * @see #isSetExcludeUnlistedClasses()
+	 * @see #unsetExcludeUnlistedClasses()
+	 * @see #isExcludeUnlistedClasses()
+	 * @generated
+	 */
+	public void setExcludeUnlistedClasses(boolean newExcludeUnlistedClasses)
+	{
+		boolean oldExcludeUnlistedClasses = excludeUnlistedClasses;
+		excludeUnlistedClasses = newExcludeUnlistedClasses;
+		boolean oldExcludeUnlistedClassesESet = excludeUnlistedClassesESet;
+		excludeUnlistedClassesESet = true;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES, oldExcludeUnlistedClasses, excludeUnlistedClasses, !oldExcludeUnlistedClassesESet));
+	}
+
+	/**
+	 * Unsets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#isExcludeUnlistedClasses <em>Exclude Unlisted Classes</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #isSetExcludeUnlistedClasses()
+	 * @see #isExcludeUnlistedClasses()
+	 * @see #setExcludeUnlistedClasses(boolean)
+	 * @generated
+	 */
+	public void unsetExcludeUnlistedClasses()
+	{
+		boolean oldExcludeUnlistedClasses = excludeUnlistedClasses;
+		boolean oldExcludeUnlistedClassesESet = excludeUnlistedClassesESet;
+		excludeUnlistedClasses = EXCLUDE_UNLISTED_CLASSES_EDEFAULT;
+		excludeUnlistedClassesESet = false;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.UNSET, PersistencePackage.PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES, oldExcludeUnlistedClasses, EXCLUDE_UNLISTED_CLASSES_EDEFAULT, oldExcludeUnlistedClassesESet));
+	}
+
+	/**
+	 * Returns whether the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#isExcludeUnlistedClasses <em>Exclude Unlisted Classes</em>}' attribute is set.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return whether the value of the '<em>Exclude Unlisted Classes</em>' attribute is set.
+	 * @see #unsetExcludeUnlistedClasses()
+	 * @see #isExcludeUnlistedClasses()
+	 * @see #setExcludeUnlistedClasses(boolean)
+	 * @generated
+	 */
+	public boolean isSetExcludeUnlistedClasses()
+	{
+		return excludeUnlistedClassesESet;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Properties</b></em>' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Properties</em>' containment reference isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Properties</em>' containment reference.
+	 * @see #setProperties(Properties)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnit_Properties()
+	 * @model containment="true"
+	 * @generated
+	 */
+	public Properties getProperties()
+	{
+		return properties;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public NotificationChain basicSetProperties(Properties newProperties, NotificationChain msgs)
+	{
+		Properties oldProperties = properties;
+		properties = newProperties;
+		if (eNotificationRequired())
+		{
+			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__PROPERTIES, oldProperties, newProperties);
+			if (msgs == null) msgs = notification; else msgs.add(notification);
+		}
+		return msgs;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit#getProperties <em>Properties</em>}' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Properties</em>' containment reference.
+	 * @see #getProperties()
+	 * @generated
+	 */
+	public void setProperties(Properties newProperties)
+	{
+		if (newProperties != properties)
+		{
+			NotificationChain msgs = null;
+			if (properties != null)
+				msgs = ((InternalEObject)properties).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - PersistencePackage.PERSISTENCE_UNIT__PROPERTIES, null, msgs);
+			if (newProperties != null)
+				msgs = ((InternalEObject)newProperties).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - PersistencePackage.PERSISTENCE_UNIT__PROPERTIES, null, msgs);
+			msgs = basicSetProperties(newProperties, msgs);
+			if (msgs != null) msgs.dispatch();
+		}
+		else if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PERSISTENCE_UNIT__PROPERTIES, newProperties, newProperties));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE_UNIT__MAPPING_FILES:
+				return ((InternalEList<?>)getMappingFiles()).basicRemove(otherEnd, msgs);
+			case PersistencePackage.PERSISTENCE_UNIT__CLASSES:
+				return ((InternalEList<?>)getClasses()).basicRemove(otherEnd, msgs);
+			case PersistencePackage.PERSISTENCE_UNIT__PROPERTIES:
+				return basicSetProperties(null, msgs);
+		}
+		return super.eInverseRemove(otherEnd, featureID, msgs);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE_UNIT__DESCRIPTION:
+				return getDescription();
+			case PersistencePackage.PERSISTENCE_UNIT__PROVIDER:
+				return getProvider();
+			case PersistencePackage.PERSISTENCE_UNIT__JTA_DATA_SOURCE:
+				return getJtaDataSource();
+			case PersistencePackage.PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE:
+				return getNonJtaDataSource();
+			case PersistencePackage.PERSISTENCE_UNIT__MAPPING_FILES:
+				return getMappingFiles();
+			case PersistencePackage.PERSISTENCE_UNIT__JAR_FILES:
+				return getJarFiles();
+			case PersistencePackage.PERSISTENCE_UNIT__CLASSES:
+				return getClasses();
+			case PersistencePackage.PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES:
+				return isExcludeUnlistedClasses() ? Boolean.TRUE : Boolean.FALSE;
+			case PersistencePackage.PERSISTENCE_UNIT__PROPERTIES:
+				return getProperties();
+			case PersistencePackage.PERSISTENCE_UNIT__NAME:
+				return getName();
+			case PersistencePackage.PERSISTENCE_UNIT__TRANSACTION_TYPE:
+				return getTransactionType();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void eSet(int featureID, Object newValue)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE_UNIT__DESCRIPTION:
+				setDescription((String)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__PROVIDER:
+				setProvider((String)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__JTA_DATA_SOURCE:
+				setJtaDataSource((String)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE:
+				setNonJtaDataSource((String)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__MAPPING_FILES:
+				getMappingFiles().clear();
+				getMappingFiles().addAll((Collection<? extends MappingFileRef>)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__JAR_FILES:
+				getJarFiles().clear();
+				getJarFiles().addAll((Collection<? extends String>)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__CLASSES:
+				getClasses().clear();
+				getClasses().addAll((Collection<? extends JavaClassRef>)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES:
+				setExcludeUnlistedClasses(((Boolean)newValue).booleanValue());
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__PROPERTIES:
+				setProperties((Properties)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__NAME:
+				setName((String)newValue);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__TRANSACTION_TYPE:
+				setTransactionType((PersistenceUnitTransactionType)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE_UNIT__DESCRIPTION:
+				setDescription(DESCRIPTION_EDEFAULT);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__PROVIDER:
+				setProvider(PROVIDER_EDEFAULT);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__JTA_DATA_SOURCE:
+				setJtaDataSource(JTA_DATA_SOURCE_EDEFAULT);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE:
+				setNonJtaDataSource(NON_JTA_DATA_SOURCE_EDEFAULT);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__MAPPING_FILES:
+				getMappingFiles().clear();
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__JAR_FILES:
+				getJarFiles().clear();
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__CLASSES:
+				getClasses().clear();
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES:
+				unsetExcludeUnlistedClasses();
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__PROPERTIES:
+				setProperties((Properties)null);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__NAME:
+				setName(NAME_EDEFAULT);
+				return;
+			case PersistencePackage.PERSISTENCE_UNIT__TRANSACTION_TYPE:
+				unsetTransactionType();
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PERSISTENCE_UNIT__DESCRIPTION:
+				return DESCRIPTION_EDEFAULT == null ? description != null : !DESCRIPTION_EDEFAULT.equals(description);
+			case PersistencePackage.PERSISTENCE_UNIT__PROVIDER:
+				return PROVIDER_EDEFAULT == null ? provider != null : !PROVIDER_EDEFAULT.equals(provider);
+			case PersistencePackage.PERSISTENCE_UNIT__JTA_DATA_SOURCE:
+				return JTA_DATA_SOURCE_EDEFAULT == null ? jtaDataSource != null : !JTA_DATA_SOURCE_EDEFAULT.equals(jtaDataSource);
+			case PersistencePackage.PERSISTENCE_UNIT__NON_JTA_DATA_SOURCE:
+				return NON_JTA_DATA_SOURCE_EDEFAULT == null ? nonJtaDataSource != null : !NON_JTA_DATA_SOURCE_EDEFAULT.equals(nonJtaDataSource);
+			case PersistencePackage.PERSISTENCE_UNIT__MAPPING_FILES:
+				return mappingFiles != null && !mappingFiles.isEmpty();
+			case PersistencePackage.PERSISTENCE_UNIT__JAR_FILES:
+				return jarFiles != null && !jarFiles.isEmpty();
+			case PersistencePackage.PERSISTENCE_UNIT__CLASSES:
+				return classes != null && !classes.isEmpty();
+			case PersistencePackage.PERSISTENCE_UNIT__EXCLUDE_UNLISTED_CLASSES:
+				return isSetExcludeUnlistedClasses();
+			case PersistencePackage.PERSISTENCE_UNIT__PROPERTIES:
+				return properties != null;
+			case PersistencePackage.PERSISTENCE_UNIT__NAME:
+				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
+			case PersistencePackage.PERSISTENCE_UNIT__TRANSACTION_TYPE:
+				return isSetTransactionType();
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString()
+	{
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (description: ");
+		result.append(description);
+		result.append(", provider: ");
+		result.append(provider);
+		result.append(", jtaDataSource: ");
+		result.append(jtaDataSource);
+		result.append(", nonJtaDataSource: ");
+		result.append(nonJtaDataSource);
+		result.append(", jarFiles: ");
+		result.append(jarFiles);
+		result.append(", excludeUnlistedClasses: ");
+		if (excludeUnlistedClassesESet) result.append(excludeUnlistedClasses); else result.append("<unset>");
+		result.append(", name: ");
+		result.append(name);
+		result.append(", transactionType: ");
+		if (transactionTypeESet) result.append(transactionType); else result.append("<unset>");
+		result.append(')');
+		return result.toString();
+	}
+
+} // PersistenceUnit
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceUnitTransactionType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceUnitTransactionType.java
new file mode 100644
index 0000000..625806e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/PersistenceUnitTransactionType.java
@@ -0,0 +1,227 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: PersistenceUnitTransactionType.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.util.Enumerator;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the literals of the enumeration '<em><b>Unit Transaction Type</b></em>',
+ * and utility methods for working with them.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getPersistenceUnitTransactionType()
+ * @model
+ * @generated
+ */
+public enum PersistenceUnitTransactionType implements Enumerator
+{
+	/**
+	 * The '<em><b>JTA</b></em>' literal object.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #JTA_VALUE
+	 * @generated
+	 * @ordered
+	 */
+	JTA(0, "JTA", "JTA"),
+
+	/**
+	 * The '<em><b>RESOURCE LOCAL</b></em>' literal object.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #RESOURCE_LOCAL_VALUE
+	 * @generated
+	 * @ordered
+	 */
+	RESOURCE_LOCAL(1, "RESOURCE_LOCAL", "RESOURCE_LOCAL");
+
+	/**
+	 * The '<em><b>JTA</b></em>' literal value.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of '<em><b>JTA</b></em>' literal object isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @see #JTA
+	 * @model
+	 * @generated
+	 * @ordered
+	 */
+	public static final int JTA_VALUE = 0;
+
+	/**
+	 * The '<em><b>RESOURCE LOCAL</b></em>' literal value.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of '<em><b>RESOURCE LOCAL</b></em>' literal object isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @see #RESOURCE_LOCAL
+	 * @model
+	 * @generated
+	 * @ordered
+	 */
+	public static final int RESOURCE_LOCAL_VALUE = 1;
+
+	/**
+	 * An array of all the '<em><b>Unit Transaction Type</b></em>' enumerators.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private static final PersistenceUnitTransactionType[] VALUES_ARRAY =
+		new PersistenceUnitTransactionType[]
+		{
+			JTA,
+			RESOURCE_LOCAL,
+		};
+
+	/**
+	 * A public read-only list of all the '<em><b>Unit Transaction Type</b></em>' enumerators.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final List<PersistenceUnitTransactionType> VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY));
+
+	/**
+	 * Returns the '<em><b>Unit Transaction Type</b></em>' literal with the specified literal value.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static PersistenceUnitTransactionType get(String literal)
+	{
+		for (int i = 0; i < VALUES_ARRAY.length; ++i)
+		{
+			PersistenceUnitTransactionType result = VALUES_ARRAY[i];
+			if (result.toString().equals(literal))
+			{
+				return result;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the '<em><b>Unit Transaction Type</b></em>' literal with the specified name.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static PersistenceUnitTransactionType getByName(String name)
+	{
+		for (int i = 0; i < VALUES_ARRAY.length; ++i)
+		{
+			PersistenceUnitTransactionType result = VALUES_ARRAY[i];
+			if (result.getName().equals(name))
+			{
+				return result;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the '<em><b>Unit Transaction Type</b></em>' literal with the specified integer value.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static PersistenceUnitTransactionType get(int value)
+	{
+		switch (value)
+		{
+			case JTA_VALUE: return JTA;
+			case RESOURCE_LOCAL_VALUE: return RESOURCE_LOCAL;
+		}
+		return null;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private final int value;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private final String name;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private final String literal;
+
+	/**
+	 * Only this class can construct instances.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private PersistenceUnitTransactionType(int value, String name, String literal)
+	{
+		this.value = value;
+		this.name = name;
+		this.literal = literal;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public int getValue()
+	{
+	  return value;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getName()
+	{
+	  return name;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getLiteral()
+	{
+	  return literal;
+	}
+
+	/**
+	 * Returns the literal value of the enumerator, which is its string representation.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString()
+	{
+		return literal;
+	}
+	
+} //PersistenceUnitTransactionType
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Properties.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Properties.java
new file mode 100644
index 0000000..96f128f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Properties.java
@@ -0,0 +1,180 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: Properties.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.NotificationChain;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Properties</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.Properties#getProperties <em>Properties</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperties()
+ * @model kind="class"
+ * @generated
+ */
+public class Properties extends EObjectImpl implements EObject
+{
+	/**
+	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getProperties()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<Property> properties;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected Properties()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass()
+	{
+		return PersistencePackage.Literals.PROPERTIES;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Properties</b></em>' containment reference list.
+	 * The list contents are of type {@link org.eclipse.jpt.core.internal.resource.persistence.Property}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Properties</em>' containment reference list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Properties</em>' containment reference list.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperties_Properties()
+	 * @model containment="true"
+	 * @generated
+	 */
+	public EList<Property> getProperties()
+	{
+		if (properties == null)
+		{
+			properties = new EObjectContainmentEList<Property>(Property.class, this, PersistencePackage.PROPERTIES__PROPERTIES);
+		}
+		return properties;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTIES__PROPERTIES:
+				return ((InternalEList<?>)getProperties()).basicRemove(otherEnd, msgs);
+		}
+		return super.eInverseRemove(otherEnd, featureID, msgs);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTIES__PROPERTIES:
+				return getProperties();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void eSet(int featureID, Object newValue)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTIES__PROPERTIES:
+				getProperties().clear();
+				getProperties().addAll((Collection<? extends Property>)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTIES__PROPERTIES:
+				getProperties().clear();
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTIES__PROPERTIES:
+				return properties != null && !properties.isEmpty();
+		}
+		return super.eIsSet(featureID);
+	}
+
+} // Properties
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Property.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Property.java
new file mode 100644
index 0000000..c95cab1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/Property.java
@@ -0,0 +1,262 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: Property.java,v 1.1 2007/07/30 20:13:46 pfullbright Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Property</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.Property#getName <em>Name</em>}</li>
+ *   <li>{@link org.eclipse.jpt.core.internal.resource.persistence.Property#getValue <em>Value</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperty()
+ * @model kind="class"
+ * @generated
+ */
+public class Property extends EObjectImpl implements EObject
+{
+	/**
+	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getName()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String NAME_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getName()
+	 * @generated
+	 * @ordered
+	 */
+	protected String name = NAME_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getValue() <em>Value</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getValue()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String VALUE_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getValue() <em>Value</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getValue()
+	 * @generated
+	 * @ordered
+	 */
+	protected String value = VALUE_EDEFAULT;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected Property()
+	{
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass()
+	{
+		return PersistencePackage.Literals.PROPERTY;
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Name</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Name</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Name</em>' attribute.
+	 * @see #setName(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperty_Name()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String" required="true"
+	 * @generated
+	 */
+	public String getName()
+	{
+		return name;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.Property#getName <em>Name</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Name</em>' attribute.
+	 * @see #getName()
+	 * @generated
+	 */
+	public void setName(String newName)
+	{
+		String oldName = name;
+		name = newName;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PROPERTY__NAME, oldName, name));
+	}
+
+	/**
+	 * Returns the value of the '<em><b>Value</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Value</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Value</em>' attribute.
+	 * @see #setValue(String)
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage#getProperty_Value()
+	 * @model unique="false" dataType="org.eclipse.emf.ecore.xml.type.String" required="true"
+	 * @generated
+	 */
+	public String getValue()
+	{
+		return value;
+	}
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.resource.persistence.Property#getValue <em>Value</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Value</em>' attribute.
+	 * @see #getValue()
+	 * @generated
+	 */
+	public void setValue(String newValue)
+	{
+		String oldValue = value;
+		value = newValue;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, PersistencePackage.PROPERTY__VALUE, oldValue, value));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTY__NAME:
+				return getName();
+			case PersistencePackage.PROPERTY__VALUE:
+				return getValue();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eSet(int featureID, Object newValue)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTY__NAME:
+				setName((String)newValue);
+				return;
+			case PersistencePackage.PROPERTY__VALUE:
+				setValue((String)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTY__NAME:
+				setName(NAME_EDEFAULT);
+				return;
+			case PersistencePackage.PROPERTY__VALUE:
+				setValue(VALUE_EDEFAULT);
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID)
+	{
+		switch (featureID)
+		{
+			case PersistencePackage.PROPERTY__NAME:
+				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
+			case PersistencePackage.PROPERTY__VALUE:
+				return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value);
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString()
+	{
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (name: ");
+		result.append(name);
+		result.append(", value: ");
+		result.append(value);
+		result.append(')');
+		return result.toString();
+	}
+
+} // Property
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/JavaClassRefTranslator.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/JavaClassRefTranslator.java
new file mode 100644
index 0000000..68fe425
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/JavaClassRefTranslator.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ *  Copyright (c) 2007 Oracle. 
+ *  All rights reserved.  This program and the accompanying materials 
+ *  are made available under the terms of the Eclipse Public License v1.0 
+ *  which accompanies this distribution, and is available at 
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *  
+ *  Contributors: 
+ *  	Oracle - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.resource.persistence.translators;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+
+public class JavaClassRefTranslator extends Translator
+{
+	private static Translator[] children;
+	
+	
+	public JavaClassRefTranslator(String domNameAndPath, EStructuralFeature feature, int style) {
+		super(domNameAndPath, feature, style);
+	}
+	
+	public JavaClassRefTranslator(String domNameAndPath, EStructuralFeature feature) {
+		super(domNameAndPath, feature);
+	}
+	
+	
+	public Translator[] getChildren(Object target, int versionID) {
+		if (children == null) {
+			children = createChildren();
+		}
+		return children;
+	}
+	
+	private static Translator[] createChildren() {
+		return new Translator[] {
+			new Translator(TEXT_ATTRIBUTE_VALUE, PersistencePackage.eINSTANCE.getJavaClassRef_JavaClass())
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/MappingFileTranslator.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/MappingFileTranslator.java
new file mode 100644
index 0000000..5e67fb0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/MappingFileTranslator.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ *  Copyright (c) 2007 Oracle. 
+ *  All rights reserved.  This program and the accompanying materials 
+ *  are made available under the terms of the Eclipse Public License v1.0 
+ *  which accompanies this distribution, and is available at 
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *  
+ *  Contributors: 
+ *  	Oracle - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.resource.persistence.translators;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+
+public class MappingFileTranslator extends Translator
+{
+	private static Translator[] children;
+	
+	
+	public MappingFileTranslator(String domNameAndPath, EStructuralFeature feature, int style) {
+		super(domNameAndPath, feature, style);
+	}
+
+	public MappingFileTranslator(String domNameAndPath, EStructuralFeature feature) {
+		super(domNameAndPath, feature);
+	}
+	
+	
+	public Translator[] getChildren(Object target, int versionID) {
+		if (children == null) {
+			children = createChildren();
+		}
+		return children;
+	}
+	
+	private static Translator[] createChildren() {
+		return new Translator[] {
+			new Translator(TEXT_ATTRIBUTE_VALUE, PersistencePackage.eINSTANCE.getMappingFileRef_FileName())
+		};
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/PersistenceTranslator.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/PersistenceTranslator.java
new file mode 100644
index 0000000..25ad387
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/PersistenceTranslator.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.resource.persistence.translators;
+
+import org.eclipse.jpt.core.internal.resource.common.translators.BooleanTranslator;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage;
+import org.eclipse.wst.common.internal.emf.resource.ConstantAttributeTranslator;
+import org.eclipse.wst.common.internal.emf.resource.GenericTranslator;
+import org.eclipse.wst.common.internal.emf.resource.IDTranslator;
+import org.eclipse.wst.common.internal.emf.resource.RootTranslator;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+
+public class PersistenceTranslator extends RootTranslator
+	implements PersistenceXMLMapper
+{
+	public static PersistenceTranslator INSTANCE = new PersistenceTranslator();
+	
+	private static Translator[] children;
+	
+	private static PersistencePackage PERSISTENCE_PKG = PersistencePackage.eINSTANCE;
+	
+	
+	public PersistenceTranslator() {
+		super(PERSISTENCE, PERSISTENCE_PKG.eINSTANCE.getPersistence());
+	}
+	
+	public Translator[] getChildren(Object target, int versionID) {
+		if (children == null) {
+			children = createChildren();
+		}
+		return children;
+	}
+	
+	private static Translator[] createChildren() {
+		return new Translator[] {
+			IDTranslator.INSTANCE,
+			createVersionTranslator(),
+			new ConstantAttributeTranslator(XML_NS, PERSISTENCE_NS_URL),
+			new ConstantAttributeTranslator(XML_NS_XSI, XSI_NS_URL),
+			new ConstantAttributeTranslator(XSI_SCHEMA_LOCATION, PERSISTENCE_NS_URL + ' ' + PERSISTENCE_SCHEMA_LOC_1_0),
+			createPersistenceUnitTranslator()
+		};
+	}
+	
+	private static Translator createVersionTranslator() {
+		return new Translator(PERSISTENCE_VERSION, PERSISTENCE_PKG.getPersistence_Version(), DOM_ATTRIBUTE);
+	}
+	
+	private static Translator createPersistenceUnitTranslator() {
+		GenericTranslator translator = new GenericTranslator(PERSISTENCE_UNIT, PERSISTENCE_PKG.getPersistence_PersistenceUnits());
+		translator.setChildren(
+			new Translator[] {
+				IDTranslator.INSTANCE,
+				createPersistenceUnitNameTranslator(),
+				createTransactionTypeTranslator(),
+				createPersistenceUnitDescriptionTranslator(),
+				createPersistenceUnitProviderTranslator(),
+				createJtaDataSourceTranslator(),
+				createNonJtaDataSourceTranslator(),
+				createMappingFileTranslator(),
+				createJarFileTranslator(),
+				createClassTranslator(),
+				createExcludeUnlistedClassesTranslator(),
+				createPropertiesTranslator()
+			}
+		);
+		return translator;
+	}
+	
+	private static Translator createPersistenceUnitNameTranslator() {
+		return new Translator(PERSISTENCE_UNIT_NAME, PERSISTENCE_PKG.getPersistenceUnit_Name(), DOM_ATTRIBUTE);
+	}
+	
+	private static Translator createTransactionTypeTranslator() {
+		return new TransactionTypeTranslator();
+	}
+	
+	private static Translator createPersistenceUnitDescriptionTranslator() {
+		return new Translator(PERSISTENCE_UNIT_DESCRIPTION, PERSISTENCE_PKG.getPersistenceUnit_Description());
+	}
+	
+	private static Translator createPersistenceUnitProviderTranslator() {
+		return new Translator(PERSISTENCE_UNIT_PROVIDER, PERSISTENCE_PKG.getPersistenceUnit_Provider(), UNSET_IF_NULL);
+	}
+	
+	private static Translator createJtaDataSourceTranslator() {
+		return new Translator(JTA_DATA_SOURCE, PERSISTENCE_PKG.getPersistenceUnit_JtaDataSource());
+	}
+	
+	private static Translator createNonJtaDataSourceTranslator() {
+		return new Translator(NON_JTA_DATA_SOURCE, PERSISTENCE_PKG.getPersistenceUnit_NonJtaDataSource());
+	}
+	
+	private static Translator createMappingFileTranslator() {
+		return new MappingFileTranslator(MAPPING_FILE, PERSISTENCE_PKG.getPersistenceUnit_MappingFiles());
+	}
+	
+	private static Translator createJarFileTranslator() {
+		return new Translator(JAR_FILE, PERSISTENCE_PKG.getPersistenceUnit_JarFiles());
+	}
+	
+	private static Translator createClassTranslator() {
+		return new JavaClassRefTranslator(CLASS, PERSISTENCE_PKG.getPersistenceUnit_Classes());
+	}
+	
+	private static Translator createExcludeUnlistedClassesTranslator() {
+		return new BooleanTranslator(EXCLUDE_UNLISTED_CLASSES, PERSISTENCE_PKG.getPersistenceUnit_ExcludeUnlistedClasses(), UNSET_IF_NULL);
+	}
+	
+	private static Translator createPropertiesTranslator() {
+		GenericTranslator translator = new GenericTranslator(PROPERTIES, PERSISTENCE_PKG.getPersistenceUnit_Properties());
+		translator.setChildren(
+			new Translator[] {
+				createPropertyTranslator()
+			}
+		);
+		return translator;
+	}
+	
+	private static Translator createPropertyTranslator() {
+		GenericTranslator translator = new GenericTranslator(PROPERTY, PERSISTENCE_PKG.getProperties_Properties(), END_TAG_NO_INDENT);
+		translator.setChildren(
+			new Translator[] {
+				createPropertyNameTranslator(),
+				createPropertyValueTranslator()
+			}
+		);
+		return translator;
+	}
+	
+	private static Translator createPropertyNameTranslator() {
+		return new Translator(PROPERTY_NAME, PERSISTENCE_PKG.getProperty_Name(), DOM_ATTRIBUTE);
+	}
+	
+	private static Translator createPropertyValueTranslator() {
+		return new Translator(PROPERTY_VALUE, PERSISTENCE_PKG.getProperty_Value(), DOM_ATTRIBUTE);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/PersistenceXMLMapper.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/PersistenceXMLMapper.java
new file mode 100644
index 0000000..d4b842c
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/PersistenceXMLMapper.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.resource.persistence.translators;
+
+public interface PersistenceXMLMapper
+{
+	String XML_NS = "xmlns";  //$NON-NLS-1$
+	String XML_NS_XSI = "xmlns:xsi";  //$NON-NLS-1$
+	String XSI_SCHEMA_LOCATION = "xsi:schemaLocation";  //$NON-NLS-1$
+	String XSI_NS_URL = "http://www.w3.org/2001/XMLSchema-instance";  //$NON-NLS-1$
+	String PERSISTENCE_NS_URL = "http://java.sun.com/xml/ns/persistence";  //$NON-NLS-1$
+	String PERSISTENCE_SCHEMA_LOC_1_0 = "http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd";  //$NON-NLS-1$
+	
+	
+	String PERSISTENCE = "persistence";  //$NON-NLS-1$
+	String PERSISTENCE_VERSION = "version";  //$NON-NLS-1$
+	String PERSISTENCE_UNIT = "persistence-unit";  //$NON-NLS-1$
+	String PERSISTENCE_UNIT_NAME = "name";  //$NON-NLS-1$
+	String PERSISTENCE_UNIT_DESCRIPTION = "description";  //$NON-NLS-1$
+	String PERSISTENCE_UNIT_PROVIDER = "provider";  //$NON-NLS-1$
+	String JTA_DATA_SOURCE = "jta-data-source";  //$NON-NLS-1$
+	String NON_JTA_DATA_SOURCE = "non-jta-data-source";  //$NON-NLS-1$
+	String MAPPING_FILE = "mapping-file";  //$NON-NLS-1$
+	String JAR_FILE = "jar-file";  //$NON-NLS-1$
+	String CLASS = "class";  //$NON-NLS-1$
+	String EXCLUDE_UNLISTED_CLASSES = "exclude-unlisted-classes";  //$NON-NLS-1$
+	String PROPERTIES = "properties";  //$NON-NLS-1$
+	String PROPERTY = "property";  //$NON-NLS-1$
+	String PROPERTY_NAME = "name";  //$NON-NLS-1$
+	String PROPERTY_VALUE = "value";  //$NON-NLS-1$
+	String TRANSACTION_TYPE = "transaction-type";  //$NON-NLS-1$
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/TransactionTypeTranslator.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/TransactionTypeTranslator.java
new file mode 100644
index 0000000..9ad3c97
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/translators/TransactionTypeTranslator.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Oracle. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.core.internal.resource.persistence.translators;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnitTransactionType;
+import org.eclipse.wst.common.internal.emf.resource.Translator;
+
+public class TransactionTypeTranslator extends Translator
+	implements PersistenceXMLMapper
+{
+	public TransactionTypeTranslator() {
+		super(TRANSACTION_TYPE, PersistencePackage.eINSTANCE.getPersistenceUnit_TransactionType());
+	}
+	
+	public Object convertStringToValue(String strValue, EObject owner) {
+		String adjStrValue = strValue;
+		String jtaStrValue = PersistenceUnitTransactionType.JTA.getName();
+		String resourceLocalStrValue = PersistenceUnitTransactionType.RESOURCE_LOCAL.getName();
+		
+		if (jtaStrValue.equals(strValue.toUpperCase())) {  //$NON-NLS-1$
+			adjStrValue = jtaStrValue;
+		}
+		else if (resourceLocalStrValue.equals(strValue.toUpperCase())) {  //$NON-NLS-1$
+			adjStrValue = resourceLocalStrValue;
+		}
+		return super.convertStringToValue(adjStrValue, owner);
+	}
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/util/PersistenceAdapterFactory.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/util/PersistenceAdapterFactory.java
new file mode 100644
index 0000000..ba8ea5d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/util/PersistenceAdapterFactory.java
@@ -0,0 +1,239 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: PersistenceAdapterFactory.java,v 1.2 2007/08/21 16:19:36 kmoore Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence.util;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef;
+import org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef;
+import org.eclipse.jpt.core.internal.resource.persistence.Persistence;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.internal.resource.persistence.Properties;
+import org.eclipse.jpt.core.internal.resource.persistence.Property;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Adapter Factory</b> for the model.
+ * It provides an adapter <code>createXXX</code> method for each class of the model.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage
+ * @generated
+ */
+public class PersistenceAdapterFactory extends AdapterFactoryImpl
+{
+	/**
+	 * The cached model package.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected static PersistencePackage modelPackage;
+
+	/**
+	 * Creates an instance of the adapter factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public PersistenceAdapterFactory()
+	{
+		if (modelPackage == null)
+		{
+			modelPackage = PersistencePackage.eINSTANCE;
+		}
+	}
+
+	/**
+	 * Returns whether this factory is applicable for the type of the object.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
+	 * <!-- end-user-doc -->
+	 * @return whether this factory is applicable for the type of the object.
+	 * @generated
+	 */
+	@Override
+	public boolean isFactoryForType(Object object)
+	{
+		if (object == modelPackage)
+		{
+			return true;
+		}
+		if (object instanceof EObject)
+		{
+			return ((EObject)object).eClass().getEPackage() == modelPackage;
+		}
+		return false;
+	}
+
+	/**
+	 * The switch the delegates to the <code>createXXX</code> methods.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected PersistenceSwitch<Adapter> modelSwitch =
+		new PersistenceSwitch<Adapter>()
+		{
+			@Override
+			public Adapter casePersistence(Persistence object)
+			{
+				return createPersistenceAdapter();
+			}
+			@Override
+			public Adapter casePersistenceUnit(PersistenceUnit object)
+			{
+				return createPersistenceUnitAdapter();
+			}
+			@Override
+			public Adapter caseMappingFileRef(MappingFileRef object)
+			{
+				return createMappingFileRefAdapter();
+			}
+			@Override
+			public Adapter caseJavaClassRef(JavaClassRef object)
+			{
+				return createJavaClassRefAdapter();
+			}
+			@Override
+			public Adapter caseProperties(Properties object)
+			{
+				return createPropertiesAdapter();
+			}
+			@Override
+			public Adapter caseProperty(Property object)
+			{
+				return createPropertyAdapter();
+			}
+			@Override
+			public Adapter defaultCase(EObject object)
+			{
+				return createEObjectAdapter();
+			}
+		};
+
+	/**
+	 * Creates an adapter for the <code>target</code>.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param target the object to adapt.
+	 * @return the adapter for the <code>target</code>.
+	 * @generated
+	 */
+	@Override
+	public Adapter createAdapter(Notifier target)
+	{
+		return modelSwitch.doSwitch((EObject)target);
+	}
+
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.jpt.core.internal.resource.persistence.Persistence <em>Persistence</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Persistence
+	 * @generated
+	 */
+	public Adapter createPersistenceAdapter()
+	{
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit <em>Unit</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit
+	 * @generated
+	 */
+	public Adapter createPersistenceUnitAdapter()
+	{
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef <em>Mapping File Ref</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef
+	 * @generated
+	 */
+	public Adapter createMappingFileRefAdapter()
+	{
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef <em>Java Class Ref</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef
+	 * @generated
+	 */
+	public Adapter createJavaClassRefAdapter()
+	{
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.jpt.core.internal.resource.persistence.Properties <em>Properties</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Properties
+	 * @generated
+	 */
+	public Adapter createPropertiesAdapter()
+	{
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.jpt.core.internal.resource.persistence.Property <em>Property</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.jpt.core.internal.resource.persistence.Property
+	 * @generated
+	 */
+	public Adapter createPropertyAdapter()
+	{
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for the default case.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @generated
+	 */
+	public Adapter createEObjectAdapter()
+	{
+		return null;
+	}
+
+} //PersistenceAdapterFactory
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/util/PersistenceSwitch.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/util/PersistenceSwitch.java
new file mode 100644
index 0000000..27f0363
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/persistence/util/PersistenceSwitch.java
@@ -0,0 +1,261 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: PersistenceSwitch.java,v 1.2 2007/08/21 16:19:36 kmoore Exp $
+ */
+package org.eclipse.jpt.core.internal.resource.persistence.util;
+
+import java.util.List;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jpt.core.internal.resource.persistence.JavaClassRef;
+import org.eclipse.jpt.core.internal.resource.persistence.MappingFileRef;
+import org.eclipse.jpt.core.internal.resource.persistence.Persistence;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage;
+import org.eclipse.jpt.core.internal.resource.persistence.PersistenceUnit;
+import org.eclipse.jpt.core.internal.resource.persistence.Properties;
+import org.eclipse.jpt.core.internal.resource.persistence.Property;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Switch</b> for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)}
+ * to invoke the <code>caseXXX</code> method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.jpt.core.internal.resource.persistence.PersistencePackage
+ * @generated
+ */
+public class PersistenceSwitch<T>
+{
+	/**
+	 * The cached model package
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected static PersistencePackage modelPackage;
+
+	/**
+	 * Creates an instance of the switch.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public PersistenceSwitch()
+	{
+		if (modelPackage == null)
+		{
+			modelPackage = PersistencePackage.eINSTANCE;
+		}
+	}
+
+	/**
+	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the first non-null result returned by a <code>caseXXX</code> call.
+	 * @generated
+	 */
+	public T doSwitch(EObject theEObject)
+	{
+		return doSwitch(theEObject.eClass(), theEObject);
+	}
+
+	/**
+	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the first non-null result returned by a <code>caseXXX</code> call.
+	 * @generated
+	 */
+	protected T doSwitch(EClass theEClass, EObject theEObject)
+	{
+		if (theEClass.eContainer() == modelPackage)
+		{
+			return doSwitch(theEClass.getClassifierID(), theEObject);
+		}
+		else
+		{
+			List<EClass> eSuperTypes = theEClass.getESuperTypes();
+			return
+				eSuperTypes.isEmpty() ?
+					defaultCase(theEObject) :
+					doSwitch(eSuperTypes.get(0), theEObject);
+		}
+	}
+
+	/**
+	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the first non-null result returned by a <code>caseXXX</code> call.
+	 * @generated
+	 */
+	protected T doSwitch(int classifierID, EObject theEObject)
+	{
+		switch (classifierID)
+		{
+			case PersistencePackage.PERSISTENCE:
+			{
+				Persistence persistence = (Persistence)theEObject;
+				T result = casePersistence(persistence);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case PersistencePackage.PERSISTENCE_UNIT:
+			{
+				PersistenceUnit persistenceUnit = (PersistenceUnit)theEObject;
+				T result = casePersistenceUnit(persistenceUnit);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case PersistencePackage.MAPPING_FILE_REF:
+			{
+				MappingFileRef mappingFileRef = (MappingFileRef)theEObject;
+				T result = caseMappingFileRef(mappingFileRef);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case PersistencePackage.JAVA_CLASS_REF:
+			{
+				JavaClassRef javaClassRef = (JavaClassRef)theEObject;
+				T result = caseJavaClassRef(javaClassRef);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case PersistencePackage.PROPERTIES:
+			{
+				Properties properties = (Properties)theEObject;
+				T result = caseProperties(properties);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case PersistencePackage.PROPERTY:
+			{
+				Property property = (Property)theEObject;
+				T result = caseProperty(property);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			default: return defaultCase(theEObject);
+		}
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Persistence</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Persistence</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T casePersistence(Persistence object)
+	{
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Unit</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Unit</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T casePersistenceUnit(PersistenceUnit object)
+	{
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Mapping File Ref</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Mapping File Ref</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T caseMappingFileRef(MappingFileRef object)
+	{
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Java Class Ref</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Java Class Ref</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T caseJavaClassRef(JavaClassRef object)
+	{
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Properties</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Properties</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T caseProperties(Properties object)
+	{
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Property</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Property</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T caseProperty(Property object)
+	{
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>EObject</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch, but this is the last case anyway.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>EObject</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+	 * @generated
+	 */
+	public T defaultCase(EObject object)
+	{
+		return null;
+	}
+
+} //PersistenceSwitch
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/.classpath b/jpa/plugins/org.eclipse.jpt.db.ui/.classpath
deleted file mode 100644
index 304e861..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/.cvsignore b/jpa/plugins/org.eclipse.jpt.db.ui/.cvsignore
deleted file mode 100644
index 814c6a8..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-bin
-build.xml
-javaCompiler...args
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/.project b/jpa/plugins/org.eclipse.jpt.db.ui/.project
deleted file mode 100644
index 88ea5da..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.db.ui</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/.settings/org.eclipse.core.resources.prefs b/jpa/plugins/org.eclipse.jpt.db.ui/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index ee4b8c1..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:10:38 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/.settings/org.eclipse.jdt.core.prefs b/jpa/plugins/org.eclipse.jpt.db.ui/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 842c286..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,7 +0,0 @@
-#Sun May 27 14:59:42 EDT 2007
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.db.ui/META-INF/MANIFEST.MF
deleted file mode 100644
index 38a4d91..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,14 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-Vendor: %providerName
-Bundle-SymbolicName: org.eclipse.jpt.db.ui
-Bundle-Version: 1.0.0.qualifier
-Bundle-ClassPath: .
-Bundle-Localization: plugin
-Export-Package: org.eclipse.jpt.db.ui.internal; x-friends:="org.eclipse.jpt.ui"
-Require-Bundle: org.eclipse.ui,
- org.eclipse.jpt.db,
- org.eclipse.datatools.connectivity.ui,
- org.eclipse.datatools.sqltools.editor.core
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/about.html b/jpa/plugins/org.eclipse.jpt.db.ui/about.html
deleted file mode 100644
index 9e73bda..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/about.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
-
-<head>
-<title>About</title>
-<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
-</head>
-
-<BODY lang="EN-US">
-
-<H3>About This Content</H3>
-
-<P>June 06, 2007</P>
-
-<H3>License</H3>
-
-<P>The Eclipse Foundation makes available all content in this plug-in 
-("Content"). Unless otherwise indicated below, the Content is provided to you 
-under the terms and conditions of the Eclipse Public License Version 1.0 
-("EPL"). A copy of the EPL is available at
-<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-
-<P>If you did not receive this Content directly from the Eclipse Foundation, the 
-Content is being redistributed by another party ("Redistributor") and different 
-terms and conditions may apply to your use of any object code in the Content. 
-Check the Redistributor's license that was provided with the Content. If no such 
-license exists, contact the Redistributor. Unless otherwise indicated below, the 
-terms and conditions of the EPL still apply to any source code in the Content 
-and such source code may be obtained at
-<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P>
-
-</BODY>
-</HTML>
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/build.properties b/jpa/plugins/org.eclipse.jpt.db.ui/build.properties
deleted file mode 100644
index 0d56981..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/build.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-###############################################################################
-# Copyright (c) 2006, 2007 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-source.. = src/
-output.. = bin/
-bin.includes = .,\
-               META-INF/,\
-               about.html,\
-               plugin.properties
-jars.compile.order = .
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/component.xml b/jpa/plugins/org.eclipse.jpt.db.ui/component.xml
deleted file mode 100644
index bf648aa..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/component.xml
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><component  xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.jpt.db.ui"><description url=""></description><component-depends unrestricted="true"></component-depends><plugin id="org.eclipse.jpt.db.ui" fragment="false"/></component>
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/plugin.properties b/jpa/plugins/org.eclipse.jpt.db.ui/plugin.properties
deleted file mode 100644
index 2b0e583..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/plugin.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-###############################################################################
-# Copyright (c) 2006 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-# ====================================================================
-# To code developer:
-#   Do NOT change the properties between this line and the
-#   "%%% END OF TRANSLATED PROPERTIES %%%" line.
-#   Make a new property name, append to the end of the file and change
-#   the code to use the new property.
-# ====================================================================
-
-# ====================================================================
-# %%% END OF TRANSLATED PROPERTIES %%%
-# ====================================================================
-
-pluginName = Java Persistence API Tools - DB UI
-providerName = Eclipse.org
-
diff --git a/jpa/plugins/org.eclipse.jpt.db.ui/src/org/eclipse/jpt/db/ui/internal/DTPUiTools.java b/jpa/plugins/org.eclipse.jpt.db.ui/src/org/eclipse/jpt/db/ui/internal/DTPUiTools.java
deleted file mode 100644
index 632fe81..0000000
--- a/jpa/plugins/org.eclipse.jpt.db.ui/src/org/eclipse/jpt/db/ui/internal/DTPUiTools.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2007 Oracle. All rights reserved.
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0, which accompanies this distribution
-* and is available at http://www.eclipse.org/legal/epl-v10.html.
-* 
-* Contributors:
-*     Oracle - initial API and implementation
-*******************************************************************************/
-package org.eclipse.jpt.db.ui.internal;
-
-import org.eclipse.datatools.connectivity.ICategory;
-import org.eclipse.datatools.connectivity.IConnectionProfile;
-import org.eclipse.datatools.connectivity.IProfileListener;
-import org.eclipse.datatools.connectivity.ProfileManager;
-import org.eclipse.datatools.connectivity.internal.ConnectionProfileManager;
-import org.eclipse.datatools.connectivity.internal.ui.wizards.CPWizardNode;
-import org.eclipse.datatools.connectivity.internal.ui.wizards.NewCPWizard;
-import org.eclipse.datatools.connectivity.internal.ui.wizards.ProfileWizardProvider;
-import org.eclipse.datatools.connectivity.ui.wizards.IWizardCategoryProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.jface.window.Window;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.jpt.db.internal.ConnectionProfileRepository;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- *  ConnectionProfileUiTools
- */
-public class DTPUiTools {
-	
-	/**
-	 * Launch the DTP New Connection Profile wizard to create a new database connection profile.
-	 * 
-	 * Returns the name of the added profile, or null if the wizard is cancelled. ConnectionProfileRepository 
-	 * can be used to retrieve the added connection profile.
-	 */
-	public static String createNewProfile() {
-		NewCPWizard wizard;
-		WizardDialog wizardDialog;
-
-		// Filter datasource category
-	  	ViewerFilter viewerFilter = new ViewerFilter() {
-
-			public boolean select( Viewer viewer, Object parentElement, Object element) {
-				
-				CPWizardNode wizardNode = ( CPWizardNode) element;
-				if( !( wizardNode.getProvider() instanceof IWizardCategoryProvider)) {
-					ICategory cat = ConnectionProfileManager.getInstance().getProvider(
-									(( ProfileWizardProvider) wizardNode.getProvider()).getProfile()).getCategory();
-					
-					// Only display wizards belong to database category
-					while( cat != null) {
-						if( cat.getId().equals( ConnectionProfileRepository.DATABASE_CATEGORY_ID))
-							return true;
-						else
-							cat = cat.getParent();
-					}
-				}
-				return false;
-			}
-		};
-		wizard = new NewCPWizard( viewerFilter, null);
-		Shell currentShell = Display.getCurrent().getActiveShell();
-		wizardDialog = new WizardDialog( currentShell, wizard);
-		wizardDialog.setBlockOnOpen( true);
-		
-		LocalProfileListener listener = new LocalProfileListener();
-		ProfileManager.getInstance().addProfileListener( listener);
-		
-		if( wizardDialog.open() == Window.CANCEL) {
-			ProfileManager.getInstance().removeProfileListener( listener);
-			return null;
-		}
-		IConnectionProfile addedProfile = listener.addedProfile;
-		ProfileManager.getInstance().removeProfileListener( listener);
-		
-		return addedProfile.getName();
-	}
-
-	private static class LocalProfileListener implements IProfileListener {
-		IConnectionProfile addedProfile;
-		
-		public void profileAdded( IConnectionProfile profile) {
-			addedProfile = profile;
-		}
-	
-		public void profileChanged( IConnectionProfile profile) {
-			// do nothing
-		}
-	
-		public void profileDeleted( IConnectionProfile profile) {
-			// do nothing
-		}
-	}
-		  
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/.classpath b/jpa/plugins/org.eclipse.jpt.gen/.classpath
deleted file mode 100644
index 304e861..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/jpa/plugins/org.eclipse.jpt.gen/.cvsignore b/jpa/plugins/org.eclipse.jpt.gen/.cvsignore
deleted file mode 100644
index 2d14989..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-bin
-@dot
-build.xml
diff --git a/jpa/plugins/org.eclipse.jpt.gen/.project b/jpa/plugins/org.eclipse.jpt.gen/.project
deleted file mode 100644
index ef2d508..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.gen</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/plugins/org.eclipse.jpt.gen/.settings/org.eclipse.core.resources.prefs b/jpa/plugins/org.eclipse.jpt.gen/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 7e690b4..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:10:55 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/jpa/plugins/org.eclipse.jpt.gen/.settings/org.eclipse.jdt.core.prefs b/jpa/plugins/org.eclipse.jpt.gen/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 3e1d50a..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,7 +0,0 @@
-#Sun May 27 14:28:54 EDT 2007
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
diff --git a/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF
deleted file mode 100644
index 0162a7c..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,15 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-Vendor: %providerName
-Bundle-SymbolicName: org.eclipse.jpt.gen
-Bundle-Version: 1.0.0.qualifier
-Bundle-ClassPath: .
-Bundle-Localization: plugin
-Export-Package: org.eclipse.jpt.gen.internal; x-friends:="org.eclipse.jpt.ui"
-Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.jdt.core,
- org.eclipse.jpt.core,
- org.eclipse.jpt.db,
- org.eclipse.jpt.utility
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/jpa/plugins/org.eclipse.jpt.gen/about.html b/jpa/plugins/org.eclipse.jpt.gen/about.html
deleted file mode 100644
index 9e73bda..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/about.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
-
-<head>
-<title>About</title>
-<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
-</head>
-
-<BODY lang="EN-US">
-
-<H3>About This Content</H3>
-
-<P>June 06, 2007</P>
-
-<H3>License</H3>
-
-<P>The Eclipse Foundation makes available all content in this plug-in 
-("Content"). Unless otherwise indicated below, the Content is provided to you 
-under the terms and conditions of the Eclipse Public License Version 1.0 
-("EPL"). A copy of the EPL is available at
-<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-
-<P>If you did not receive this Content directly from the Eclipse Foundation, the 
-Content is being redistributed by another party ("Redistributor") and different 
-terms and conditions may apply to your use of any object code in the Content. 
-Check the Redistributor's license that was provided with the Content. If no such 
-license exists, contact the Redistributor. Unless otherwise indicated below, the 
-terms and conditions of the EPL still apply to any source code in the Content 
-and such source code may be obtained at
-<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P>
-
-</BODY>
-</HTML>
diff --git a/jpa/plugins/org.eclipse.jpt.gen/build.properties b/jpa/plugins/org.eclipse.jpt.gen/build.properties
deleted file mode 100644
index 41837eb..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/build.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-################################################################################
-# Copyright (c) 2006, 2007 Oracle. All rights reserved.
-# This program and the accompanying materials are made available under the
-# terms of the Eclipse Public License v1.0, which accompanies this distribution
-# and is available at http://www.eclipse.org/legal/epl-v10.html.
-# 
-# Contributors:
-#     Oracle - initial API and implementation
-################################################################################
-source.. = src/
-output.. = bin/
-bin.includes = .,\
-               META-INF/,\
-               about.html,\
-               plugin.properties
-jars.compile.order = .
diff --git a/jpa/plugins/org.eclipse.jpt.gen/component.xml b/jpa/plugins/org.eclipse.jpt.gen/component.xml
deleted file mode 100644
index 7a4e04e..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/component.xml
+++ /dev/null
@@ -1 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?><component  xmlns="http://eclipse.org/wtp/releng/tools/component-model" name="org.eclipse.jpt.gen"><description url=""></description><component-depends unrestricted="true"></component-depends><plugin id="org.eclipse.jpt.gen" fragment="false"/></component>
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.gen/plugin.properties b/jpa/plugins/org.eclipse.jpt.gen/plugin.properties
deleted file mode 100644
index 4875a8b..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/plugin.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-# ====================================================================
-# To code developer:
-#   Do NOT change the properties between this line and the
-#   "%%% END OF TRANSLATED PROPERTIES %%%" line.
-#   Make a new property name, append to the end of the file and change
-#   the code to use the new property.
-# ====================================================================
-
-# ====================================================================
-# %%% END OF TRANSLATED PROPERTIES %%%
-# ====================================================================
-
-pluginName = Java Persistence API Tools - Entity Gen
-providerName = Eclipse.org
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/EntityGenerator.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/EntityGenerator.java
deleted file mode 100644
index f1e6b92..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/EntityGenerator.java
+++ /dev/null
@@ -1,1459 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.lang.reflect.Modifier;
-import java.text.Collator;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IJavaModelStatusConstants;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jpt.core.internal.content.java.mappings.JPA;
-import org.eclipse.jpt.db.internal.Column;
-import org.eclipse.jpt.db.internal.ForeignKey;
-import org.eclipse.jpt.db.internal.Table;
-import org.eclipse.jpt.utility.internal.IndentingPrintWriter;
-import org.eclipse.jpt.utility.internal.JavaType;
-import org.eclipse.jpt.utility.internal.StringTools;
-import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
-
-// TODO handle table names that are illegal class names
-// TODO handle table names that are illegal file names
-// TODO handle column names that are illegal field/method names
-// TODO format code per preferences
-// TODO organize imports per preferences
-// TODO prompt user to overwrite existing classes
-/**
- * This generator will generate an entity for a table.
- */
-public class EntityGenerator {
-	final Config config;
-	private final IPackageFragment packageFragment;
-	private final GenTable genTable;
-	private final String entityClassName;
-	private final OverwriteConfirmer overwriteConfirmer;
-	private final IProgressMonitor monitor;
-	private final String pkClassName;
-
-
-	// ********** public API **********
-
-	public static void generateEntity(Config config, IPackageFragment packageFragment, GenTable genTable, OverwriteConfirmer overwriteConfirmer, IProgressMonitor monitor) {
-		if ((config == null) || (packageFragment == null) || (genTable == null)) {
-			throw new NullPointerException();
-		}
-		new EntityGenerator(config, packageFragment, genTable, overwriteConfirmer, monitor).generateEntity();
-	}
-
-
-	// ********** constructor/initialization **********
-
-	private EntityGenerator(Config config, IPackageFragment packageFragment, GenTable genTable, OverwriteConfirmer overwriteConfirmer, IProgressMonitor monitor) {
-		super();
-		this.config = config;
-		this.packageFragment = packageFragment;
-		this.genTable = genTable;
-		this.entityClassName = this.fullyQualify(this.entityName());
-		this.overwriteConfirmer = overwriteConfirmer;
-		this.monitor = monitor;
-		this.pkClassName = this.entityClassName + "PK";  // hack
-	}
-
-
-	// ********** code gen **********
-
-	private void generateEntity() {
-		int totalWork = pkClassIsGenerated() ? 40 : 20;
-		try {
-			this.monitor.beginTask("", totalWork);
-			this.generateEntity_();
-		} catch (JavaModelException ex) {
-			throw new RuntimeException(ex);
-		}
-		finally {
-			this.monitor.done();
-		}
-	}
-
-	private void generateEntity_() throws JavaModelException {
-		// build the body source first so we can gather up the import statements
-		this.generateSourceFile(this.entityClassName, this.entityName() + ".java", this.buildSource(this.buildBodySource()));
-		if (this.pkClassIsGenerated()) {
-			this.generateSourceFile(this.pkClassName, this.pkName() + ".java", this.buildSource(this.buildPKBodySource()));
-		}
-		
-	}
-
-	private void generateSourceFile(String className, String fileName, String source) throws JavaModelException {
-		try {
-			this.packageFragment.createCompilationUnit(fileName, source, false, new SubProgressMonitor(this.monitor, 10));
-		} catch (JavaModelException ex) {
-			if (ex.getJavaModelStatus().getCode() == IJavaModelStatusConstants.NAME_COLLISION) {
-				if (this.overwriteConfirmer.overwrite(className)) {
-					this.packageFragment.createCompilationUnit(fileName, source, true, new SubProgressMonitor(this.monitor, 0));
-				}
-			} else {
-				throw ex;
-			}
-		}
-	}
-
-	/**
-	 * build the "body" source first; then build the "package" and "imports" source
-	 * and concatenate the "body" source to it
-	 */
-	private String buildSource(BodySource bodySource) {
-		StringWriter sw = new StringWriter(bodySource.length() + 1000);
-		PrintWriter pw = new PrintWriter(sw);
-		this.printPackageAndImportsOn(pw, bodySource);
-		pw.print(bodySource.source());
-		this.monitor.worked(10);
-		return sw.toString();
-	}
-
-	private BodySource buildBodySource() {
-		EntitySourceWriter pw = new EntitySourceWriter(this.packageName(), this.entityClassName);
-		this.printBodySourceOn(pw);
-		return pw;
-	}
-
-	private BodySource buildPKBodySource() {
-		EntitySourceWriter pw = new EntitySourceWriter(this.packageName(), this.pkClassName);
-		this.printPrimaryKeyClassOn(pw);
-		return pw;
-	}
-
-	private void printBodySourceOn(EntitySourceWriter pw) {
-		this.printClassDeclarationOn(pw);
-
-		pw.indent();
-			this.printEntityPrimaryKeyFieldsOn(pw);
-			this.printEntityNonPrimaryKeyBasicFieldsOn(pw);
-			this.printEntityManyToOneFieldsOn(pw);
-			this.printEntityOneToManyFieldsOn(pw);
-			this.printEntityOwnedManyToManyFieldsOn(pw);
-			this.printEntityNonOwnedManyToManyFieldsOn(pw);
-			this.printSerialVersionUID(pw);
-			pw.println();
-
-			this.printZeroArgumentConstructorOn(this.entityName(), this.config.methodVisibility(), pw);
-			if (this.config.propertyAccessType() || this.config.generateGettersAndSetters()) {
-				this.printEntityPrimaryKeyGettersAndSettersOn(pw);
-				this.printEntityNonPrimaryKeyBasicGettersAndSettersOn(pw);
-				this.printEntityManyToOneGettersAndSettersOn(pw);
-				this.printEntityOneToManyGettersAndSettersOn(pw);
-				this.printEntityOwnedManyToManyGettersAndSettersOn(pw);
-				this.printEntityNonOwnedManyToManyGettersAndSettersOn(pw);
-			}
-		pw.undent();
-
-		pw.print('}');
-		pw.println();
-	}
-
-	private void printClassDeclarationOn(EntitySourceWriter pw) {
-		this.printEntityAnnotationOn(pw);
-		this.printTableAnnotationOn(pw);
-		this.printIdClassAnnotationOn(pw);
-
-		pw.print("public class ");
-		pw.printTypeDeclaration(this.entityClassName);
-		if (config.serializable()) {
-			pw.print(" implements ");
-			pw.printTypeDeclaration(Serializable.class.getName());
-		}
-		pw.print(" {");
-		pw.println();
-	}
-
-	private void printEntityAnnotationOn(EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.ENTITY);
-		pw.println();
-	}
-
-	private void printTableAnnotationOn(EntitySourceWriter pw) {
-		if ( ! this.table().matchesShortJavaClassName(this.entityName())) {
-			pw.printAnnotation(JPA.TABLE);
-			pw.print("(name=\"");
-			pw.print(this.table().getName());
-			pw.print("\")");
-			pw.println();
-		}
-	}
-
-	private void printIdClassAnnotationOn(EntitySourceWriter pw) {
-		if (this.pkClassIsGenerated() && this.config.generateIdClassForCompoundPK()) {
-			pw.printAnnotation(JPA.ID_CLASS);
-			pw.print('(');
-			pw.printTypeDeclaration(pkClassName);
-			pw.print(".class)");
-			pw.println();
-		}
-	}
-
-	private void printEntityPrimaryKeyFieldsOn(EntitySourceWriter pw) {
-		if (this.pkClassIsGenerated() && this.config.generateEmbeddedIdForCompoundPK()) {
-			this.printEntityEmbeddedIdPrimaryKeyFieldOn(pw);
-		} else {
-			this.printEntityReadOnlyPrimaryKeyFieldsOn(pw);
-			this.printEntityWritablePrimaryKeyFieldsOn(pw);
-		}
-	}
-
-	private void printEntityEmbeddedIdPrimaryKeyFieldOn(EntitySourceWriter pw) {
-		if (this.config.fieldAccessType()) {
-			pw.printAnnotation(JPA.EMBEDDED_ID);
-			pw.println();
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(this.pkClassName);
-		pw.print(' ');
-		pw.print(this.genTable.fieldNameForEmbeddedId());
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printEntityReadOnlyPrimaryKeyFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.genTable.readOnlyPrimaryKeyColumns(); stream.hasNext(); ) {
-			this.printEntityReadOnlyPrimaryKeyFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityReadOnlyPrimaryKeyFieldOn(Column column, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(column);
-		if (this.config.fieldAccessType()) {
-			pw.printAnnotation(JPA.ID);
-			pw.println();
-			if (column.matchesJavaFieldName(fieldName)) {
-				this.printReadOnlyColumnAnnotationOn(pw);  // no Column name needed
-			} else {
-				this.printReadOnlyColumnAnnotationOn(column.getName(), pw);
-			}
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(column.javaTypeDeclaration());
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printReadOnlyColumnAnnotationOn(String columnName, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.COLUMN);
-		pw.print("(name=\"");
-		pw.print(columnName);
-		pw.print("\", insertable=false, updatable=false)");
-		pw.println();
-	}
-
-	private void printReadOnlyColumnAnnotationOn(EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.COLUMN);
-		pw.print("(insertable=false, updatable=false)");
-		pw.println();
-	}
-
-	private void printEntityWritablePrimaryKeyFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.genTable.writablePrimaryKeyColumns(); stream.hasNext(); ) {
-			this.printEntityWritablePrimaryKeyFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityWritablePrimaryKeyFieldOn(Column column, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(column);
-		if (this.config.fieldAccessType()) {
-			pw.printAnnotation(JPA.ID);
-			pw.println();
-			if ( ! column.matchesJavaFieldName(fieldName)) {
-				this.printColumnAnnotationOn(column.getName(), pw);
-			}
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(column.javaTypeDeclaration());
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printEntityNonPrimaryKeyBasicFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.genTable.nonPrimaryKeyBasicColumns(); stream.hasNext(); ) {
-			this.printEntityNonPrimaryKeyBasicFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityNonPrimaryKeyBasicFieldOn(Column column, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(column);
-		if (this.config.fieldAccessType()) {
-			if ( ! column.matchesJavaFieldName(fieldName)) {
-				this.printColumnAnnotationOn(column.getName(), pw);
-			}
-		}
-		if (column.isLob()) {
-			pw.printAnnotation(JPA.LOB);
-			pw.println();
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(column.javaTypeDeclaration());
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printColumnAnnotationOn(String columnName, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.COLUMN);
-		pw.print("(name=\"");
-		pw.print(columnName);
-		pw.print("\")");
-		pw.println();
-	}
-
-	private void printEntityManyToOneFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<ManyToOneRelation> stream = this.genTable.manyToOneRelations(); stream.hasNext(); ) {
-			this.printEntityManyToOneFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityManyToOneFieldOn(ManyToOneRelation relation, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(relation);
-		if (this.config.fieldAccessType()) {
-			this.printManyToOneAnnotationOn(fieldName, relation, pw);
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(this.fullyQualify(relation.referencedEntityName()));
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printManyToOneAnnotationOn(String fieldName, ManyToOneRelation relation, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.MANY_TO_ONE);
-		pw.println();
-		ForeignKey fk = relation.getForeignKey();
-		if (fk.matchesJavaFieldName(fieldName)) {
-			return;  // no JoinColumn annotation needed
-		}
-		if (fk.referencesSingleColumnPrimaryKey()) {
-			pw.printAnnotation(JPA.JOIN_COLUMN);
-			pw.print("(name=\"");
-			pw.print(fk.columnPairs().next().getBaseColumn().getName());
-			pw.print("\")");
-		} else {
-			if (fk.columnPairsSize() > 1) {
-				pw.printAnnotation(JPA.JOIN_COLUMNS);
-				pw.print("({");
-				pw.println();
-				pw.indent();
-			}
-			this.printJoinColumnAnnotationsOn(fk, pw);
-			if (fk.columnPairsSize() > 1) {
-				pw.undent();
-				pw.println();
-				pw.print("})");
-			}
-		}
-		pw.println();
-	}
-
-	private void printJoinColumnAnnotationsOn(ForeignKey foreignKey, EntitySourceWriter pw) {
-		for (Iterator<ForeignKey.ColumnPair> stream = foreignKey.columnPairs(); stream.hasNext(); ) {
-			this.printJoinColumnAnnotationOn(stream.next(), pw);
-			if (stream.hasNext()) {
-				pw.println(',');
-			}
-		}
-	}
-
-	private void printJoinColumnAnnotationOn(ForeignKey.ColumnPair columnPair, EntitySourceWriter pw) {
-		this.printJoinColumnAnnotationOn(columnPair.getBaseColumn().getName(), columnPair.getReferencedColumn().getName(), pw);
-	}
-
-	/**
-	 * assume that at least one of the two names is not null
-	 */
-	private void printJoinColumnAnnotationOn(String baseColumnName, String referencedColumnName, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.JOIN_COLUMN);
-		pw.print('(');
-		if (baseColumnName != null) {
-			pw.print("name=\"");
-			pw.print(baseColumnName);
-		}
-		if (referencedColumnName != null) {
-			if (baseColumnName != null) {
-				pw.print("\", ");
-			}
-			pw.print("referencedColumnName=\"");
-			pw.print(referencedColumnName);
-		}
-		pw.print("\")");
-	}
-
-	private void printEntityOneToManyFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<OneToManyRelation> stream = this.genTable.oneToManyRelations(); stream.hasNext(); ) {
-			this.printEntityOneToManyFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityOneToManyFieldOn(OneToManyRelation relation, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(relation);
-		if (this.config.fieldAccessType()) {
-			this.printOneToManyAnnotationOn(fieldName, relation, pw);
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(this.config.getCollectionTypeName());
-		pw.print('<');
-		pw.printTypeDeclaration(this.fullyQualify(relation.referencedEntityName()));
-		pw.print('>');
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printOneToManyAnnotationOn(String fieldName, OneToManyRelation relation, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.ONE_TO_MANY);
-		pw.print("(mappedBy=\"");
-		pw.print(relation.mappedBy());
-		pw.print("\")");
-		pw.println();
-	}
-
-	private void printEntityOwnedManyToManyFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<ManyToManyRelation>  stream = this.genTable.ownedManyToManyRelations(); stream.hasNext(); ) {
-			this.printEntityOwnedManyToManyFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityOwnedManyToManyFieldOn(ManyToManyRelation relation, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(relation);
-		if (this.config.fieldAccessType()) {
-			this.printOwnedManyToManyAnnotationOn(fieldName, relation, pw);
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(this.config.getCollectionTypeName());
-		pw.print('<');
-		pw.printTypeDeclaration(this.fullyQualify(relation.nonOwningEntityName()));
-		pw.print('>');
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	/**
-	 * I guess you could build a state machine for all this crap,
-	 * but that seems like overkill...
-	 */
-	private void printOwnedManyToManyAnnotationOn(String fieldName, ManyToManyRelation relation, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.MANY_TO_MANY);
-		pw.println();
-		boolean first = true;
-		boolean comma = false;
-		if ( ! relation.joinTableNameIsDefault()) {
-			if (first) {
-				first = false;
-				pw.printAnnotation(JPA.JOIN_TABLE);
-				pw.print('(');
-			}
-			pw.print("name=\"");
-			pw.print(relation.getJoinTable().name());
-			pw.print('\"');
-			comma = true;
-		}
-		if ( ! relation.joinColumnsIsDefaultFor(fieldName)) {
-			if (first) {
-				first = false;
-				pw.printAnnotation(JPA.JOIN_TABLE);
-				pw.print('(');
-			} else if (comma) {
-				pw.print(',');
-			}
-			pw.println();
-			pw.indent();
-			this.printJoinTableJoinColumnsOn("joinColumns", fieldName, relation.getOwningForeignKey(), pw);
-			pw.undent();
-			comma = true;
-		}
-		String inverseFieldName = relation.getNonOwningTable().fieldNameFor(relation);
-		if ( ! relation.inverseJoinColumnsIsDefaultFor(inverseFieldName)) {
-			if (first) {
-				first = false;
-				pw.printAnnotation(JPA.JOIN_TABLE);
-				pw.print('(');
-			} else if (comma) {
-				pw.print(',');
-			}
-			pw.println();
-			pw.indent();
-			this.printJoinTableJoinColumnsOn("inverseJoinColumns", inverseFieldName, relation.getNonOwningForeignKey(), pw);
-			pw.undent();
-			comma = true;
-		}
-		if ( ! first) {
-			pw.print(')');
-		}
-		pw.println();
-	}
-
-	private void printJoinTableJoinColumnsOn(String elementName, String fieldName, ForeignKey foreignKey, EntitySourceWriter pw) {
-		if (foreignKey.columnPairsSize() != 1) {
-			this.printJoinTableJoinColumnsOn(elementName, foreignKey, pw);
-		} else if (foreignKey.getReferencedTable().primaryKeyColumnsSize() != 1) {
-			// if the referenced table has a composite primary key, neither of the columns can be a default
-			// since both of the defaults require a single-column primary key
-			this.printJoinTableJoinColumnsOn(elementName, foreignKey, pw);
-		} else {
-			ForeignKey.ColumnPair columnPair = foreignKey.columnPairs().next();
-			Column pkColumn = foreignKey.getReferencedTable().primaryKeyColumns().next();
-			if (columnPair.getBaseColumn().matchesJavaFieldName(fieldName + "_" + pkColumn.getName())) {
-				if (columnPair.getReferencedColumn() == pkColumn) {
-					// we shouldn't get here...
-				} else {
-					pw.print(elementName);
-					pw.print('=');
-					this.printJoinColumnAnnotationOn(null, columnPair.getReferencedColumn().getName(), pw);
-				}
-			} else {
-				if (columnPair.getReferencedColumn() == pkColumn) {
-					pw.print(elementName);
-					pw.print('=');
-					this.printJoinColumnAnnotationOn(columnPair.getBaseColumn().getName(), null, pw);
-				} else {
-					this.printJoinTableJoinColumnsOn(elementName, foreignKey, pw);
-				}
-			}
-		}
-	}
-
-	private void printJoinTableJoinColumnsOn(String elementName, ForeignKey foreignKey, EntitySourceWriter pw) {
-		pw.print(elementName);
-		pw.print('=');
-		if (foreignKey.columnPairsSize() > 1) {
-			pw.print('{');
-			pw.println();
-			pw.indent();
-		}
-		this.printJoinColumnAnnotationsOn(foreignKey, pw);
-		if (foreignKey.columnPairsSize() > 1) {
-			pw.undent();
-			pw.println();
-			pw.print('}');
-			pw.println();
-		}
-	}
-
-	private void printEntityNonOwnedManyToManyFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<ManyToManyRelation> stream = this.genTable.nonOwnedManyToManyRelations(); stream.hasNext(); ) {
-			this.printEntityNonOwnedManyToManyFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityNonOwnedManyToManyFieldOn(ManyToManyRelation relation, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(relation);
-		if (this.config.fieldAccessType()) {
-			this.printNonOwnedManyToManyAnnotationOn(fieldName, relation, pw);
-		}
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(this.config.getCollectionTypeName());
-		pw.print('<');
-		pw.printTypeDeclaration(this.fullyQualify(relation.owningEntityName()));
-		pw.print('>');
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-		pw.println();
-	}
-
-	private void printNonOwnedManyToManyAnnotationOn(String fieldName, ManyToManyRelation relation, EntitySourceWriter pw) {
-		pw.printAnnotation(JPA.MANY_TO_MANY);
-		pw.print("(mappedBy=\"");
-		pw.print(relation.getMappedBy());
-		pw.print("\")");
-		pw.println();
-	}
-
-	private String fullyQualify(String shortClassName) {
-		String pkg = this.packageName();
-		return (pkg.length() == 0) ? shortClassName : pkg + '.' + shortClassName;
-	}
-
-	private void printSerialVersionUID(EntitySourceWriter pw) {
-		if (this.config.generateSerialVersionUID()) {
-			pw.print("private static final long serialVersionUID = 1L;");
-			pw.println();
-		}
-	}
-
-	private void printZeroArgumentConstructorOn(String ctorName, String visibility, EntitySourceWriter pw) {
-		if (this.config.generateDefaultConstructor()) {
-			pw.printVisibility(visibility);
-			pw.print(ctorName);
-			pw.print("() {");
-			pw.println();
-			pw.indent();
-				pw.println("super();");
-			pw.undent();
-			pw.print('}');
-			pw.println();
-			pw.println();
-		}
-	}
-
-	private void printEntityPrimaryKeyGettersAndSettersOn(EntitySourceWriter pw) {
-		if (this.pkClassIsGenerated() && this.config.generateEmbeddedIdForCompoundPK()) {
-			this.printEntityEmbeddedIdPrimaryKeyGetterAndSetterOn(pw);
-		} else {
-			this.printEntityReadOnlyPrimaryKeyGettersAndSettersOn(pw);
-			this.printEntityWritablePrimaryKeyGettersAndSettersOn(pw);
-		}
-	}
-
-	private void printEntityEmbeddedIdPrimaryKeyGetterAndSetterOn(EntitySourceWriter pw) {
-		if (this.config.propertyAccessType()) {
-			pw.printAnnotation(JPA.EMBEDDED_ID);
-			pw.println();
-		}
-		pw.printGetterAndSetter(this.genTable.fieldNameForEmbeddedId(), this.pkClassName, this.config.methodVisibility());
-	}
-
-	private void printEntityReadOnlyPrimaryKeyGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.genTable.readOnlyPrimaryKeyColumns(); stream.hasNext(); ) {
-			this.printEntityReadOnlyPrimaryKeyGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityReadOnlyPrimaryKeyGetterAndSetterOn(Column column, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(column);
-		if (this.config.propertyAccessType()) {
-			pw.printAnnotation(JPA.ID);
-			pw.println();
-			if (column.matchesJavaFieldName(propertyName)) {
-				this.printReadOnlyColumnAnnotationOn(pw);  // no Column name needed
-			} else {
-				this.printReadOnlyColumnAnnotationOn(column.getName(), pw);
-			}
-		}
-
-		pw.printGetterAndSetter(propertyName, column.javaTypeDeclaration(), this.config.methodVisibility());
-	}
-
-	private void printEntityWritablePrimaryKeyGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.genTable.writablePrimaryKeyColumns(); stream.hasNext(); ) {
-			this.printEntityWritablePrimaryKeyGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityWritablePrimaryKeyGetterAndSetterOn(Column column, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(column);
-		if (this.config.propertyAccessType()) {
-			pw.printAnnotation(JPA.ID);
-			pw.println();
-			if ( ! column.matchesJavaFieldName(propertyName)) {
-				this.printColumnAnnotationOn(column.getName(), pw);
-			}
-		}
-
-		pw.printGetterAndSetter(propertyName, column.javaTypeDeclaration(), this.config.methodVisibility());
-	}
-
-	private void printEntityNonPrimaryKeyBasicGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.genTable.nonPrimaryKeyBasicColumns(); stream.hasNext(); ) {
-			this.printEntityNonPrimaryKeyBasicGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityNonPrimaryKeyBasicGetterAndSetterOn(Column column, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(column);
-		if (this.config.propertyAccessType()) {
-			if ( ! column.matchesJavaFieldName(propertyName)) {
-				this.printColumnAnnotationOn(column.getName(), pw);
-			}
-		}
-
-		pw.printGetterAndSetter(propertyName, column.javaTypeDeclaration(), this.config.methodVisibility());
-	}
-
-	private void printEntityManyToOneGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<ManyToOneRelation> stream = this.genTable.manyToOneRelations(); stream.hasNext(); ) {
-			this.printEntityManyToOneGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityManyToOneGetterAndSetterOn(ManyToOneRelation relation, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(relation);
-		if (this.config.propertyAccessType()) {
-			this.printManyToOneAnnotationOn(propertyName, relation, pw);
-		}
-
-		String typeDeclaration = this.fullyQualify(relation.referencedEntityName());
-		pw.printGetterAndSetter(propertyName, typeDeclaration, this.config.methodVisibility());
-	}
-
-	private void printEntityOneToManyGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<OneToManyRelation> stream = this.genTable.oneToManyRelations(); stream.hasNext(); ) {
-			this.printEntityOneToManyGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityOneToManyGetterAndSetterOn(OneToManyRelation relation, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(relation);
-		if (this.config.propertyAccessType()) {
-			this.printOneToManyAnnotationOn(propertyName, relation, pw);
-		}
-
-		String elementTypeDeclaration = this.fullyQualify(relation.referencedEntityName());
-		pw.printCollectionGetterAndSetter(propertyName, this.config.getCollectionTypeName(), elementTypeDeclaration, this.config.methodVisibility());
-	}
-
-	private void printEntityOwnedManyToManyGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<ManyToManyRelation> stream = this.genTable.ownedManyToManyRelations(); stream.hasNext(); ) {
-			this.printEntityOwnedManyToManyGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityOwnedManyToManyGetterAndSetterOn(ManyToManyRelation relation, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(relation);
-		if (this.config.propertyAccessType()) {
-			this.printOwnedManyToManyAnnotationOn(propertyName, relation, pw);
-		}
-
-		String elementTypeDeclaration = this.fullyQualify(relation.nonOwningEntityName());
-		pw.printCollectionGetterAndSetter(propertyName, this.config.getCollectionTypeName(), elementTypeDeclaration, this.config.methodVisibility());
-	}
-
-	private void printEntityNonOwnedManyToManyGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<ManyToManyRelation> stream = this.genTable.nonOwnedManyToManyRelations(); stream.hasNext(); ) {
-			this.printEntityNonOwnedManyToManyGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printEntityNonOwnedManyToManyGetterAndSetterOn(ManyToManyRelation relation, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(relation);
-		if (this.config.propertyAccessType()) {
-			this.printNonOwnedManyToManyAnnotationOn(propertyName, relation, pw);
-		}
-
-		String elementTypeDeclaration = this.fullyQualify(relation.owningEntityName());
-		pw.printCollectionGetterAndSetter(propertyName, this.config.getCollectionTypeName(), elementTypeDeclaration, this.config.methodVisibility());
-	}
-
-	private void printPrimaryKeyClassOn(EntitySourceWriter pw) {
-		if (this.config.generateEmbeddedIdForCompoundPK()) {
-			pw.printAnnotation(JPA.EMBEDDABLE);
-			pw.println();
-		}
-		pw.print("public class ");
-		pw.printTypeDeclaration(this.pkClassName);
-		pw.print(" implements ");
-		pw.printTypeDeclaration(Serializable.class.getName());
-		pw.print(" {");
-		pw.println();
-
-		pw.indent();
-			this.printIdFieldsOn(pw);
-			this.printSerialVersionUID(pw);
-			pw.println();
-			this.printZeroArgumentConstructorOn(this.pkName(), "public", pw);
-
-			if (this.config.propertyAccessType() || this.config.generateGettersAndSetters()) {
-				this.printIdGettersAndSettersOn(pw);
-			}
-
-			this.printEqualsMethodOn(this.pkName(), this.table().primaryKeyColumns(), pw);
-			this.printHashCodeMethodOn(this.table().primaryKeyColumns(), pw);
-		pw.undent();
-
-		pw.print('}');
-		pw.println();
-	}
-
-	private void printIdFieldsOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.table().primaryKeyColumns(); stream.hasNext(); ) {
-			this.printIdFieldOn(stream.next(), pw);
-		}
-	}
-
-	private void printIdFieldOn(Column column, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(column);
-		pw.printVisibility(this.config.fieldVisibility());
-		pw.printTypeDeclaration(column.javaTypeDeclaration());
-		pw.print(' ');
-		pw.print(fieldName);
-		pw.print(';');
-		pw.println();
-	}
-
-	private void printIdGettersAndSettersOn(EntitySourceWriter pw) {
-		for (Iterator<Column> stream = this.table().primaryKeyColumns(); stream.hasNext(); ) {
-			this.printIdGetterAndSetterOn(stream.next(), pw);
-		}
-	}
-
-	private void printIdGetterAndSetterOn(Column column, EntitySourceWriter pw) {
-		String propertyName = this.genTable.fieldNameFor(column);
-		pw.printGetterAndSetter(propertyName, column.javaTypeDeclaration(), this.config.methodVisibility());
-	}
-
-	private void printEqualsMethodOn(String className, Iterator<Column> columns, EntitySourceWriter pw) {
-		pw.printAnnotation("java.lang.Override");
-		pw.println();
-
-		pw.println("public boolean equals(Object o) {");
-		pw.indent();
-			pw.println("if (o == this) {");
-			pw.indent();
-				pw.println("return true;");
-			pw.undent();
-			pw.print('}');
-			pw.println();
-
-			pw.print("if ( ! (o instanceof ");
-			pw.print(className);
-			pw.print(")) {");
-			pw.println();
-			pw.indent();
-				pw.println("return false;");
-			pw.undent();
-			pw.print('}');
-			pw.println();
-
-			pw.print(className);
-			pw.print(" other = (");
-			pw.print(className);
-			pw.print(") o;");
-			pw.println();
-
-			pw.print("return ");
-			pw.indent();
-				while (columns.hasNext()) {
-					this.printEqualsClauseOn(columns.next(), pw);
-					if (columns.hasNext()) {
-						pw.println();
-						pw.print("&& ");
-					}
-				}
-				pw.print(';');
-				pw.println();
-			pw.undent();
-		pw.undent();
-		pw.print('}');
-		pw.println();
-		pw.println();
-	}
-
-	private void printEqualsClauseOn(Column column, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(column);
-		JavaType javaType = column.javaType();
-		if (javaType.isPrimitive()) {
-			this.printPrimitiveEqualsClauseOn(fieldName, pw);
-		} else {
-			this.printReferenceEqualsClauseOn(fieldName, pw);
-		}
-	}
-
-	private void printPrimitiveEqualsClauseOn(String fieldName, EntitySourceWriter pw) {
-		pw.print("(this.");
-		pw.print(fieldName);
-		pw.print(" == other.");
-		pw.print(fieldName);
-		pw.print(')');
-	}
-
-	private void printReferenceEqualsClauseOn(String fieldName, EntitySourceWriter pw) {
-		pw.print("this.");
-		pw.print(fieldName);
-		pw.print(".equals(other.");
-		pw.print(fieldName);
-		pw.print(')');
-	}
-
-	private void printHashCodeMethodOn(Iterator<Column> columns, EntitySourceWriter pw) {
-		pw.printAnnotation("java.lang.Override");
-		pw.println();
-
-		pw.println("public int hashCode() {");
-		pw.indent();
-			pw.print("return ");
-			pw.indent();
-				while (columns.hasNext()) {
-					this.printHashCodeClauseOn(columns.next(), pw);
-					if (columns.hasNext()) {
-						pw.println();
-						pw.print("^ ");
-					}
-				}
-				pw.print(';');
-				pw.println();
-			pw.undent();
-		pw.undent();
-		pw.print('}');
-		pw.println();
-		pw.println();
-	}
-
-	private void printHashCodeClauseOn(Column column, EntitySourceWriter pw) {
-		String fieldName = this.genTable.fieldNameFor(column);
-		JavaType javaType = column.javaType();
-		if (javaType.isPrimitive()) {
-			this.printPrimitiveHashCodeClauseOn(javaType.getElementTypeName(), fieldName, pw);
-		} else {
-			this.printReferenceHashCodeClauseOn(fieldName, pw);
-		}
-	}
-
-	private void printPrimitiveHashCodeClauseOn(String primitiveName, String fieldName, EntitySourceWriter pw) {
-		if (primitiveName.equals("int") || primitiveName.equals("short") || primitiveName.equals("byte") || primitiveName.equals("char")) {
-			pw.print("this.");
-			pw.print(fieldName);
-		} else if (primitiveName.equals("long")) {  // cribbed from Long#hashCode()
-			// ((int) (this.value ^ (this.value >>> 32)))
-			pw.print("((int) (this.");
-			pw.print(fieldName);
-			pw.print(" ^ (this.");
-			pw.print(fieldName);
-			pw.print(" >>> 32)))");
-		} else if (primitiveName.equals("double")) {  // cribbed from Double#hashCode()
-			//	((int) (java.lang.Double.doubleToLongBits(this.value) ^ (java.lang.Double.doubleToLongBits(this.value) >>> 32)))
-			pw.print("((int) (");
-			pw.printTypeDeclaration("java.lang.Double");
-			pw.print(".doubleToLongBits(this.");
-			pw.print(fieldName);
-			pw.print(") ^ (");
-			pw.printTypeDeclaration("java.lang.Double");
-			pw.print(".doubleToLongBits(this.");
-			pw.print(fieldName);
-			pw.print(") >>> 32)))");
-		} else if (primitiveName.equals("float")) {  // cribbed from Float#hashCode()
-			// java.lang.Float.floatToIntBits(this.value)
-			pw.printTypeDeclaration("java.lang.Float");
-			pw.print(".floatToIntBits(this.");
-			pw.print(fieldName);
-			pw.print(')');
-		} else if (primitiveName.equals("boolean")) {  // cribbed from Boolean#hashCode()
-			// (this.value ? 1231 : 1237)
-			pw.print("(this.");
-			pw.print(fieldName);
-			pw.print(" ? 1231 : 1237)");
-		} else {
-			throw new IllegalArgumentException(primitiveName);
-		}
-	}
-
-	private void printReferenceHashCodeClauseOn(String fieldName, EntitySourceWriter pw) {
-		pw.print("this.");
-		pw.print(fieldName);
-		pw.print(".hashCode()");
-	}
-
-	private void printPackageAndImportsOn(PrintWriter pw, BodySource bodySource) {
-		if (this.packageName().length() != 0) {
-			pw.print("package ");
-			pw.print(this.packageName());
-			pw.print(';');
-			pw.println();
-			pw.println();
-		}
-
-		for (Iterator<Map.Entry<String, String>> stream = bodySource.importEntries(); stream.hasNext(); ) {
-			Map.Entry<String, String> entry = stream.next();
-			pw.print("import ");
-			pw.print(entry.getValue());  // package
-			pw.print('.');
-			pw.print(entry.getKey());  // short class name
-			pw.print(';');
-			pw.println();
-		}
-		pw.println();
-	}
-
-
-	// ********** convenience methods **********
-
-	private String packageName() {
-		return this.packageFragment.getElementName();
-	}
-
-	private Table table() {
-		return this.genTable.getTable();
-	}
-
-	private String entityName() {
-		return this.genTable.getEntityName();
-	}
-
-	private String pkName() {
-		return this.entityName() + "PK";  // hack
-	}
-
-	private boolean pkClassIsGenerated() {
-		return this.table().primaryKeyColumnsSize() > 1;
-	}
-
-
-	// ********** writer **********
-
-	private interface BodySource {
-
-		/**
-		 * return a sorted set of map entries; the key is the short class name,
-		 * the value is the package name
-		 */
-		Iterator<Map.Entry<String, String>> importEntries();
-
-		/**
-		 * return the body source code
-		 */
-		String source();
-
-		/**
-		 * return the length of the body source code
-		 */
-		int length();
-
-	}
-
-	/**
-	 * Extend IndentingPrintWriter with some methods that facilitate building
-	 * class source code.
-	 */
-	private static class EntitySourceWriter extends IndentingPrintWriter implements BodySource {
-		final String packageName;
-		final String className;
-		// key = short class name; value = package name
-		private final Map<String, String> imports = new HashMap<String, String>();
-
-		EntitySourceWriter(String packageName, String className) {
-			super(new StringWriter(20000));
-			this.packageName = packageName;
-			this.className = className;
-		}
-
-		void printVisibility(String visibilityModifier) {
-			if (visibilityModifier.length() != 0) {
-				this.print(visibilityModifier);
-				this.print(' ');
-			}
-		}
-
-		void printAnnotation(String annotationName) {
-			this.print('@');
-			this.printTypeDeclaration(annotationName);
-		}
-
-		void printTypeDeclaration(String typeDeclaration) {
-			this.print(this.importedTypeDeclaration(typeDeclaration));
-		}
-
-		/**
-		 * Return the specified class's "imported" name.
-		 * The class declaration must be of the form:
-		 *     "int"
-		 *     "int[]" (not "[I")
-		 *     "java.lang.Object"
-		 *     "java.lang.Object[]" (not "[Ljava.lang.Object;")
-		 *     "java.util.Map.Entry" (not "java.util.Map$Entry")
-		 *     "java.util.Map.Entry[][]" (not "[[Ljava.util.Map$Entry;")
-		 */
-		private String importedTypeDeclaration(String typeDeclaration) {
-			if (this.typeDeclarationIsMemberClass(typeDeclaration)) {
-				// no need for an import, just return the partially-qualified name
-				return this.memberClassTypeDeclaration(typeDeclaration);
-			}
-			int last = typeDeclaration.lastIndexOf('.');
-			String pkg = (last == -1) ? "" : typeDeclaration.substring(0, last);
-			String shortTypeDeclaration = typeDeclaration.substring(last + 1);
-			String shortElementTypeName = shortTypeDeclaration;
-			while (shortElementTypeName.endsWith("[]")) {
-				shortElementTypeName = shortElementTypeName.substring(0, shortElementTypeName.length() - 2);
-			}
-			String prev = this.imports.get(shortElementTypeName);
-			if (prev == null) {
-				// this is the first class with this short element type name
-				this.imports.put(shortElementTypeName, pkg);
-				return shortTypeDeclaration;
-			}
-			if (prev.equals(pkg)) {
-				// this element type has already been imported
-				return shortTypeDeclaration;
-			}
-			// another class with the same short element type name has been
-			// previously imported, so this one must be used fully-qualified
-			return typeDeclaration;
-		}
-
-		/**
-		 * e.g. "foo.bar.Employee.PK" will return true
-		 */
-		private boolean typeDeclarationIsMemberClass(String typeDeclaration) {
-			return (typeDeclaration.length() > this.className.length())
-					&& typeDeclaration.startsWith(this.className)
-					&& (typeDeclaration.charAt(this.className.length()) == '.');
-		}
-
-		/**
-		 * e.g. "foo.bar.Employee.PK" will return "Employee.PK"
-		 * this prevents collisions with other imported classes (e.g. "joo.jar.PK")
-		 */
-		private String memberClassTypeDeclaration(String typeDeclaration) {
-			int index = this.packageName.length();
-			if (index != 0) {
-				index++;  // bump past the '.'
-			}
-			return typeDeclaration.substring(index);
-		}
-
-		public Iterator<Map.Entry<String, String>> importEntries() {
-			return new FilteringIterator<Map.Entry<String, String>>(this.sortedImportEntries()) {
-				@Override
-				protected boolean accept(Object next) {
-					@SuppressWarnings("unchecked")
-					String pkg = ((Map.Entry<String, String>) next).getValue();
-					if (pkg.equals("")
-							|| pkg.equals("java.lang")
-							|| pkg.equals(EntitySourceWriter.this.packageName)) {
-						return false;
-					}
-					return true;
-				}
-			};
-		}
-
-		private Iterator<Map.Entry<String, String>> sortedImportEntries() {
-			TreeSet<Map.Entry<String, String>> sortedImports = new TreeSet<Map.Entry<String, String>>(this.buildImportEntriesComparator());
-			sortedImports.addAll(this.imports.entrySet());
-			return sortedImports.iterator();
-		}
-
-		private Comparator<Map.Entry<String, String>> buildImportEntriesComparator() {
-			return new Comparator<Map.Entry<String, String>>() {
-				public int compare(Map.Entry<String, String> e1, Map.Entry<String, String> e2) {
-					Collator collator = Collator.getInstance();
-					int pkg = collator.compare(e1.getValue(), e2.getValue());
-					return (pkg == 0) ? collator.compare(e1.getKey(), e2.getKey()) : pkg;
-				}
-			};
-		}
-
-		void printGetterAndSetter(String propertyName, String typeDeclaration, String visibility) {
-			this.printGetter(propertyName, typeDeclaration, visibility);
-			this.println();
-			this.println();
-
-			this.printSetter(propertyName, typeDeclaration, visibility);
-			this.println();
-			this.println();
-		}
-
-		private void printGetter(String propertyName, String typeDeclaration, String visibility) {
-			this.printVisibility(visibility);
-			this.printTypeDeclaration(typeDeclaration);
-			this.print(' ');
-			this.print(typeDeclaration.equals("boolean") ? "is" : "get");
-			this.print(StringTools.capitalize(propertyName));
-			this.print("() {");
-			this.println();
-
-			this.indent();
-				this.print("return this.");
-				this.print(propertyName);
-				this.print(';');
-				this.println();
-			this.undent();
-
-			this.print('}');
-		}
-
-		private void printSetter(String propertyName, String typeDeclaration, String visibility) {
-			this.printVisibility(visibility);
-			this.print("void set");
-			this.print(StringTools.capitalize(propertyName));
-			this.print('(');
-			this.printTypeDeclaration(typeDeclaration);
-			this.print(' ');
-			this.print(propertyName);
-			this.print(") {");
-			this.println();
-
-			this.indent();
-				this.print("this.");
-				this.print(propertyName);
-				this.print(" = ");
-				this.print(propertyName);
-				this.print(';');
-				this.println();
-			this.undent();
-
-			this.print('}');
-		}
-
-		void printCollectionGetterAndSetter(String propertyName, String collectionTypeDeclaration, String elementTypeDeclaration, String visibility) {
-			this.printCollectionGetter(propertyName, collectionTypeDeclaration, elementTypeDeclaration, visibility);
-			this.println();
-			this.println();
-
-			this.printCollectionSetter(propertyName, collectionTypeDeclaration, elementTypeDeclaration, visibility);
-			this.println();
-			this.println();
-		}
-
-		private void printCollectionGetter(String propertyName, String collectionTypeDeclaration, String elementTypeDeclaration, String visibility) {
-			this.printVisibility(visibility);
-			this.printTypeDeclaration(collectionTypeDeclaration);
-			this.print('<');
-			this.printTypeDeclaration(elementTypeDeclaration);
-			this.print("> get");
-			this.print(StringTools.capitalize(propertyName));
-			this.print("() {");
-			this.println();
-
-			this.indent();
-				this.print("return this.");
-				this.print(propertyName);
-				this.print(';');
-				this.println();
-			this.undent();
-
-			this.print('}');
-		}
-
-		private void printCollectionSetter(String propertyName, String collectionTypeDeclaration, String elementTypeDeclaration, String visibility) {
-			this.printVisibility(visibility);
-			this.print("void set");
-			this.print(StringTools.capitalize(propertyName));
-			this.print('(');
-			this.printTypeDeclaration(collectionTypeDeclaration);
-			this.print('<');
-			this.printTypeDeclaration(elementTypeDeclaration);
-			this.print('>');
-			this.print(' ');
-			this.print(propertyName);
-			this.print(") {");
-			this.println();
-
-			this.indent();
-				this.print("this.");
-				this.print(propertyName);
-				this.print(" = ");
-				this.print(propertyName);
-				this.print(';');
-				this.println();
-			this.undent();
-
-			this.print('}');
-		}
-
-		public String source() {
-			return this.out.toString();
-		}
-
-		public int length() {
-			return ((StringWriter) this.out).getBuffer().length();
-		}
-
-	}
-
-
-	// ********** config **********
-
-	public static class Config {
-		private boolean convertToCamelCase = true;
-		private boolean propertyAccessType = false;  // as opposed to "field"
-		private String collectionTypeName = Set.class.getName();
-		private int fieldVisibility = Modifier.PRIVATE;
-		private int methodVisibility = Modifier.PUBLIC;
-		private boolean generateGettersAndSetters = true;
-		private boolean generateDefaultConstructor = true;
-		private boolean serializable = true;
-		private boolean generateSerialVersionUID = true;
-		private boolean generateEmbeddedIdForCompoundPK = true;  // as opposed to IdClass
-		private Map<Table, String> overrideEntityNames = new HashMap<Table, String>();
-
-		public static final int PRIVATE = 0;
-		public static final int PACKAGE = 1;
-		public static final int PROTECTED = 2;
-		public static final int PUBLIC = 3;
-
-
-		public boolean convertToCamelCase() {
-			return this.convertToCamelCase;
-		}
-		public void setConvertToCamelCase(boolean convertToCamelCase) {
-			this.convertToCamelCase = convertToCamelCase;
-		}
-
-		public boolean propertyAccessType() {
-			return this.propertyAccessType;
-		}
-		public void setPropertyAccessType(boolean propertyAccessType) {
-			this.propertyAccessType = propertyAccessType;
-		}
-
-		public boolean fieldAccessType() {
-			return ! this.propertyAccessType;
-		}
-		public void setFieldAccessType(boolean fieldAccessType) {
-			this.propertyAccessType = ! fieldAccessType;
-		}
-
-		public String getCollectionTypeName() {
-			return this.collectionTypeName;
-		}
-		public void setCollectionTypeName(String collectionTypeName) {
-			this.collectionTypeName = collectionTypeName;
-		}
-
-		public int getFieldVisibility() {
-			return this.fieldVisibility;
-		}
-		/** entity fields cannot be 'public' */
-		public void setFieldVisibility(int fieldVisibility) {
-			switch (fieldVisibility) {
-				case PRIVATE:
-				case PACKAGE:
-				case PROTECTED:
-					this.fieldVisibility = fieldVisibility;
-					break;
-				default:
-					throw new IllegalArgumentException("invalid field visibility: " + fieldVisibility);
-			}
-		}
-		String fieldVisibility() {
-			switch (this.fieldVisibility) {
-				case PRIVATE:
-					return "private";
-				case PACKAGE:
-					return "";
-				case PROTECTED:
-					return "protected";
-				default:
-					throw new IllegalStateException("invalid field visibility: " + this.fieldVisibility);
-			}
-		}
-
-		public int getMethodVisibility() {
-			return this.methodVisibility;
-		}
-		/** entity properties must be 'public' or 'protected' */
-		public void setMethodVisibility(int methodVisibility) {
-			switch (methodVisibility) {
-				case PROTECTED:
-				case PUBLIC:
-					this.methodVisibility = methodVisibility;
-					break;
-				default:
-					throw new IllegalArgumentException("invalid method visibility: " + methodVisibility);
-			}
-		}
-		String methodVisibility() {
-			switch (this.methodVisibility) {
-				case PROTECTED:
-					return "protected";
-				case PUBLIC:
-					return "public";
-				default:
-					throw new IllegalStateException("invalid method visibility: " + this.methodVisibility);
-			}
-		}
-
-		public boolean generateGettersAndSetters() {
-			return this.generateGettersAndSetters;
-		}
-		public void setGenerateGettersAndSetters(boolean generateGettersAndSetters) {
-			this.generateGettersAndSetters = generateGettersAndSetters;
-		}
-
-		public boolean generateDefaultConstructor() {
-			return this.generateDefaultConstructor;
-		}
-		public void setGenerateDefaultConstructor(boolean generateDefaultConstructor) {
-			this.generateDefaultConstructor = generateDefaultConstructor;
-		}
-
-		public boolean serializable() {
-			return this.serializable;
-		}
-		public void setSerializable(boolean serializable) {
-			this.serializable = serializable;
-		}
-
-		public boolean generateSerialVersionUID() {
-			return this.generateSerialVersionUID;
-		}
-		public void setGenerateSerialVersionUID(boolean generateSerialVersionUID) {
-			this.generateSerialVersionUID = generateSerialVersionUID;
-		}
-
-		public boolean generateEmbeddedIdForCompoundPK() {
-			return this.generateEmbeddedIdForCompoundPK;
-		}
-		public void setGenerateEmbeddedIdForCompoundPK(boolean generateEmbeddedIdForCompoundPK) {
-			this.generateEmbeddedIdForCompoundPK = generateEmbeddedIdForCompoundPK;
-		}
-
-		public boolean generateIdClassForCompoundPK() {
-			return ! this.generateEmbeddedIdForCompoundPK;
-		}
-		public void setGenerateIdClassForCompoundPK(boolean generateIdClassForCompoundPK) {
-			this.generateEmbeddedIdForCompoundPK = ! generateIdClassForCompoundPK;
-		}
-
-		/**
-		 * key = table
-		 * value = user-supplied override entity name
-		 */
-		public String getOverrideEntityName(Table table) {
-			return this.overrideEntityNames.get(table);
-		}
-		public void setOverrideEntityName(Table table, String overrideEntityName) {
-			this.overrideEntityNames.put(table, overrideEntityName);
-		}
-		public void clearOverrideEntityNames() {
-			this.overrideEntityNames.clear();
-		}
-		public void setOverrideEntityNames(Map<Table, String> overrideEntityNames) {
-			this.clearOverrideEntityNames();
-			for (Map.Entry<Table, String> entry : overrideEntityNames.entrySet()) {
-				this.setOverrideEntityName(entry.getKey(), entry.getValue());
-			}
-		}
-
-	}
-
-
-	// ********** config **********
-
-	public static interface OverwriteConfirmer {
-		/**
-		 * Return whether the entity generator should overwrite the specified
-		 * file.
-		 */
-		boolean overwrite(String className);
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/GenScope.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/GenScope.java
deleted file mode 100644
index f5b07dc..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/GenScope.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jpt.db.internal.Table;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
-
-class GenScope {
-	private final Map<Table, GenTable> genTables = new HashMap<Table, GenTable>();
-
-	private IProgressMonitor progressMonitor;
-	
-	// ********** construction/initialization **********
-
-	GenScope(Collection<Table> tables, EntityGenerator.Config entityConfig, IProgressMonitor progressMonitor) {
-		super();
-		this.initialize(tables, entityConfig, progressMonitor);
-	}
-
-	private void checkCanceled() {
-		if (this.progressMonitor.isCanceled()) {
-			throw new OperationCanceledException();
-		}		
-	}
-	
-	private void initialize(Collection<Table> tables, EntityGenerator.Config entityConfig, IProgressMonitor monitor) {
-		this.progressMonitor = monitor;
-		try {
-			this.progressMonitor.beginTask("", 1000);
-			this.buildGenTables(tables, entityConfig);
-			checkCanceled();
-			this.configureManyToManyRelations();
-			checkCanceled();
-			this.configureManyToOneRelations();
-			checkCanceled();
-			this.configureFieldNames();
-			checkCanceled();
-		}
-		finally {
-			this.progressMonitor.done();
-		}
-	}
-
-	private void buildGenTables(Collection<Table> tables, EntityGenerator.Config entityConfig) {
-		int size = tables.size();
-		// pass around a growing list of the entity names so we can avoid duplicates
-		Set<String> entityNames = new HashSet<String>(size);
-		for (Table table : tables) {
-			this.buildGenTable(table, entityConfig, entityNames);
-			this.progressMonitor.worked(50/size);
-		}
-	}
-
-	private void buildGenTable(Table table, EntityGenerator.Config entityConfig, Collection<String> entityNames) {
-		this.genTables.put(table, new GenTable(this, table, entityConfig, entityNames));
-	}
-
-	/**
-	 * find all the "join" tables
-	 */
-	private void configureManyToManyRelations() {
-		int tablesSize = CollectionTools.size(this.tables());
-
-		//first time takes the longest, should we take that into account?
-		for (Iterator<GenTable> stream = this.tables(); stream.hasNext(); ) {
-			checkCanceled();
-			stream.next().configureManyToManyRelations();
-			this.progressMonitor.worked(750/tablesSize);
-		}
-		// revert any "join" table that is referenced by another table back to an "entity" table
-		Set<GenTable> referencedTables = this.buildReferencedTables();
-		tablesSize = CollectionTools.size(this.joinTables());
-		for (Iterator<GenTable> stream = this.joinTables(); stream.hasNext(); ) {
-			GenTable joinGenTable = stream.next();
-			if (referencedTables.contains(joinGenTable)) {
-				joinGenTable.clearJoinTableRelation();
-			}
-			this.progressMonitor.worked(50/tablesSize);
-		}
-	}
-
-	/**
-	 * find all the many-to-one and one-to-many relations
-	 */
-	private void configureManyToOneRelations() {
-		int tablesSize = CollectionTools.size(this.entityTables());
-		for (Iterator<GenTable> stream = this.entityTables(); stream.hasNext(); ) {
-			stream.next().configureManyToOneRelations();
-			this.progressMonitor.worked(50/tablesSize);
-		}
-	}
-
-	/**
-	 * determine all the Java field names up-front because we will
-	 * need them for things like 'mappedBy' annotation elements
-	 */
-	private void configureFieldNames() {
-		int tablesSize = CollectionTools.size(this.entityTables());
-		for (Iterator<GenTable> stream = this.entityTables(); stream.hasNext(); ) {
-			stream.next().configureFieldNames();
-			this.progressMonitor.worked(50/tablesSize);
-		}
-	}
-
-
-	// ********** package API **********
-
-	/**
-	 * return only the gen tables that are suitable for generating
-	 * entities (i.e. exclude the "join" tables)
-	 */
-	Iterator<GenTable> entityTables() {
-		return new FilteringIterator<GenTable>(this.tables()) {
-			@Override
-			protected boolean accept(Object next) {
-				return ! ((GenTable) next).isJoinTable();
-			}
-		};
-	}
-
-	int numEntityTables() {
-		return CollectionTools.size(entityTables());
-	}
-	
-	/**
-	 * return the gen table corresponding to the specified table
-	 */
-	GenTable genTable(Table table) {
-		return this.genTables.get(table);
-	}
-
-
-	// ********** internal API **********
-
-	private Iterator<GenTable> tables() {
-		return this.genTables.values().iterator();
-	}
-
-	/**
-	 * return only the "join" gen tables
-	 */
-	private Iterator<GenTable> joinTables() {
-		return new FilteringIterator<GenTable>(this.tables()) {
-			@Override
-			protected boolean accept(Object next) {
-				return ((GenTable) next).isJoinTable();
-			}
-		};
-	}
-
-	/**
-	 * build a set of the tables that are referenced by other tables
-	 * in the scope
-	 */
-	private Set<GenTable> buildReferencedTables() {
-		int size = CollectionTools.size(this.tables());
-		Set<GenTable> referencedTables = new HashSet<GenTable>(this.genTables.size());
-		for (Iterator<GenTable> stream = this.tables(); stream.hasNext(); ) {
-			stream.next().addReferencedTablesTo(referencedTables);
-			this.progressMonitor.worked(50/size);
-		}
-		return referencedTables;
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/GenTable.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/GenTable.java
deleted file mode 100644
index ea7fd3d..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/GenTable.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import org.eclipse.jpt.db.internal.Column;
-import org.eclipse.jpt.db.internal.ForeignKey;
-import org.eclipse.jpt.db.internal.Table;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-import org.eclipse.jpt.utility.internal.NameTools;
-import org.eclipse.jpt.utility.internal.StringTools;
-import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
-
-/**
- * associate a table with the various relations that will be used when
- * generating the entity
- */
-class GenTable {
-	private final GenScope scope;
-	private final Table table;
-	private final EntityGenerator.Config entityConfig;
-	private final String entityName;
-	private ManyToManyRelation joinTableRelation;
-	private Collection<ManyToManyRelation> ownedManyToManyRelations = new ArrayList<ManyToManyRelation>();
-	private Collection<ManyToManyRelation> nonOwnedManyToManyRelations = new ArrayList<ManyToManyRelation>();
-	private Collection<ManyToOneRelation> manyToOneRelations = new ArrayList<ManyToOneRelation>();
-	private Collection<OneToManyRelation> oneToManyRelations = new ArrayList<OneToManyRelation>();
-	private Set<Column> foreignKeyColumns = new HashSet<Column>();
-
-	// key=column/relation; value=name
-	private final Map<Object, String> fieldNames = new HashMap<Object, String>();
-
-	private static final Object EMBEDDED_ID_VIRTUAL_COLUMN = new Object();
-
-
-	// ********** construction/initialization **********
-
-	GenTable(GenScope scope, Table table, EntityGenerator.Config entityConfig, Collection<String> entityNames) {
-		super();
-		this.scope = scope;
-		this.table = table;
-		this.entityConfig = entityConfig;
-		this.entityName = this.buildEntityName(entityNames);
-	}
-
-	private String buildEntityName(Collection<String> entityNames) {
-		String name = this.table.shortJavaClassName();
-		String overrideEntityName = this.entityConfig.getOverrideEntityName(this.table);
-		if (overrideEntityName == null) {
-			if (this.entityConfig.convertToCamelCase()) {
-				name = StringTools.convertUnderscoresToCamelCase(name);
-			}
-		} else {
-			name = overrideEntityName;
-		}
-		name = NameTools.uniqueNameForIgnoreCase(name, entityNames);
-		entityNames.add(name);
-		return name;
-	}
-
-
-	// ********** package API **********
-
-	/**
-	 * determine whether the table is a "join" table within the table's scope
-	 */
-	void configureManyToManyRelations() {
-		if (this.table.foreignKeysSize() != 2) {
-			// the table must have exactly 2 foreign keys
-			return;
-		}
-		for (Iterator<Column> stream = this.table.columns(); stream.hasNext(); ) {
-			if ( ! this.table.foreignKeyColumnsContains(stream.next())) {
-				// all the table's columns must belong to one (or both) of the 2 foreign keys
-				return;
-			}
-		}
-		Iterator<ForeignKey> fKeys = this.table.foreignKeys();
-		ForeignKey owningFK = fKeys.next();
-		ForeignKey nonOwningFK = fKeys.next();
-		GenTable owningTable = this.scope.genTable(owningFK.getReferencedTable());
-		GenTable nonOwningTable = this.scope.genTable(nonOwningFK.getReferencedTable());
-		if ((owningTable == null) || (nonOwningTable == null)) {
-			// both tables must be in the scope
-			return;
-		}
-		this.joinTableRelation = new ManyToManyRelation(this, owningFK, owningTable, nonOwningFK, nonOwningTable);
-	}
-
-	void addReferencedTablesTo(Set<GenTable> referencedTables) {
-		for (Iterator<ForeignKey> stream = this.table.foreignKeys(); stream.hasNext(); ) {
-			ForeignKey fk = stream.next();
-			GenTable genTable = this.scope.genTable(fk.getReferencedTable());
-			if (genTable != null) {
-				referencedTables.add(genTable);
-			}
-		}
-	}
-
-	void clearJoinTableRelation() {
-		this.joinTableRelation.clear();
-		this.joinTableRelation = null;
-	}
-
-	/**
-	 * find "in-scope" foreign keys
-	 */
-	void configureManyToOneRelations() {
-		for (Iterator<ForeignKey> stream = this.table.foreignKeys(); stream.hasNext(); ) {
-			ForeignKey fk = stream.next();
-			GenTable referencedtable = this.scope.genTable(fk.getReferencedTable());
-			if (referencedtable == null) {
-				continue;  // skip to next FK
-			}
-			this.manyToOneRelations.add(new ManyToOneRelation(this, fk, referencedtable));
-		}
-	}
-
-	/**
-	 * now that all the relations are in place, we can configure the Java
-	 * field names
-	 */
-	void configureFieldNames() {
-		Set<Column> columns = CollectionTools.set(this.table.columns());
-		if ((this.table.primaryKeyColumnsSize() > 1) && this.entityConfig.generateEmbeddedIdForCompoundPK()) {
-			// if we are going to generate an EmbeddedId field, add it to
-			// 'fieldNames' so we don't collide with it later, when generating
-			// field names for the columns etc.
-			this.configureFieldName(EMBEDDED_ID_VIRTUAL_COLUMN, "pk");
-		}
-		this.configureManyToOneFieldNames(columns);
-		this.configureBasicFieldNames(columns);
-		this.configureOneToManyFieldNames();
-		this.configureOwnedManyToManyFieldNames();
-		this.configureNonOwnedManyToManyFieldNames();
-	}
-
-	/**
-	 * return the columns that are part of the table's primary key
-	 * but are also part of an "in-scope" foreign key
-	 */
-	public Iterator<Column> readOnlyPrimaryKeyColumns() {
-		return new FilteringIterator<Column>(this.table.primaryKeyColumns()) {
-			@Override
-			protected boolean accept(Object column) {
-				return GenTable.this.foreignKeyColumnsContains((Column) column);
-			}
-		};
-	}
-
-	/**
-	 * return the columns that are part of the table's primary key
-	 * but are NOT part of any "in-scope" foreign key
-	 */
-	Iterator<Column> writablePrimaryKeyColumns() {
-		return new FilteringIterator<Column>(this.table.primaryKeyColumns()) {
-			@Override
-			protected boolean accept(Object column) {
-				return ! GenTable.this.foreignKeyColumnsContains((Column) column);
-			}
-		};
-	}
-
-	/**
-	 * return the columns that NEITHER part of the table's primary key
-	 * NOR part of any foreign key
-	 */
-	public Iterator<Column> nonPrimaryKeyBasicColumns() {
-		return new FilteringIterator<Column>(this.table.columns()) {
-			@Override
-			protected boolean accept(Object column) {
-				return ! (GenTable.this.primaryKeyColumnsContains((Column) column)
-						|| GenTable.this.foreignKeyColumnsContains((Column) column));
-			}
-		};
-	}
-
-	Table getTable() {
-		return this.table;
-	}
-
-	String getEntityName() {
-		return this.entityName;
-	}
-
-	boolean isJoinTable() {
-		return this.joinTableRelation != null;
-	}
-
-	void addOwnedManyToManyRelation(ManyToManyRelation relation) {
-		this.ownedManyToManyRelations.add(relation);
-	}
-
-	void removeOwnedManyToManyRelation(ManyToManyRelation relation) {
-		this.ownedManyToManyRelations.remove(relation);
-	}
-
-	void addNonOwnedManyToManyRelation(ManyToManyRelation relation) {
-		this.nonOwnedManyToManyRelations.add(relation);
-	}
-
-	void removeNonOwnedManyToManyRelation(ManyToManyRelation relation) {
-		this.nonOwnedManyToManyRelations.remove(relation);
-	}
-
-	void addOneToManyRelation(OneToManyRelation relation) {
-		this.oneToManyRelations.add(relation);
-	}
-
-	String javaFieldName() {
-		return this.table.javaFieldName();
-	}
-
-	Iterator<ManyToOneRelation> manyToOneRelations() {
-		return this.manyToOneRelations.iterator();
-	}
-
-	Iterator<OneToManyRelation> oneToManyRelations() {
-		return this.oneToManyRelations.iterator();
-	}
-
-	Iterator<ManyToManyRelation> ownedManyToManyRelations() {
-		return this.ownedManyToManyRelations.iterator();
-	}
-
-	Iterator<ManyToManyRelation> nonOwnedManyToManyRelations() {
-		return this.nonOwnedManyToManyRelations.iterator();
-	}
-
-	/**
-	 * the key can be a column or relation
-	 */
-	private String fieldNameForInternal(Object o) {
-		return this.fieldNames.get(o);
-	}
-
-	/**
-	 * this will return null if we don't want an embedded id field
-	 */
-	String fieldNameForEmbeddedId() {
-		return this.fieldNameForInternal(EMBEDDED_ID_VIRTUAL_COLUMN);
-	}
-
-	String fieldNameFor(Column column) {
-		return this.fieldNameForInternal(column);
-	}
-
-	String fieldNameFor(ManyToOneRelation relation) {
-		return this.fieldNameForInternal(relation);
-	}
-
-	String fieldNameFor(OneToManyRelation relation) {
-		return this.fieldNameForInternal(relation);
-	}
-
-	String fieldNameFor(ManyToManyRelation relation) {
-		return this.fieldNameForInternal(relation);
-	}
-
-	String name() {
-		return this.table.getName();
-	}
-
-
-	// ********** internal API **********
-
-	/**
-	 * while we are figuring out the names for the m:1 fields, remove from the
-	 * specified set of columns the columns that are only part of the foreign keys
-	 */
-	private void configureManyToOneFieldNames(Set<Column> columns) {
-		for (ManyToOneRelation relation : this.manyToOneRelations) {
-			CollectionTools.removeAll(columns, relation.getForeignKey().nonPrimaryKeyBaseColumns());
-			CollectionTools.addAll(this.foreignKeyColumns, relation.getForeignKey().baseColumns());
-			relation.setMappedBy(this.configureFieldName(relation, relation.javaFieldName()));
-		}
-	}
-
-	private String configureFieldName(Object o, String fieldName) {
-		fieldName = this.camelCase(fieldName);
-		fieldName = NameTools.uniqueNameFor(fieldName, this.fieldNames.values());
-		this.fieldNames.put(o, fieldName);
-		return fieldName;
-	}
-
-	private String camelCase(String name) {
-		return this.entityConfig.convertToCamelCase() ?
-			StringTools.convertUnderscoresToCamelCase(name, false)  // false = don't capitalize first letter
-		:
-			name;
-	}
-
-	/**
-	 * build a unique field name for the specified "basic" columns,
-	 * checking for name collisions
-	 */
-	private void configureBasicFieldNames(Set<Column> columns) {
-		for (Column column : columns) {
-			this.configureFieldName(column, column.javaFieldName());
-		}
-	}
-
-	private void configureOneToManyFieldNames() {
-		for (OneToManyRelation relation : this.oneToManyRelations) {
-			this.configureFieldName(relation, relation.javaFieldName());
-		}
-	}
-
-	private void configureOwnedManyToManyFieldNames() {
-		for (ManyToManyRelation relation : this.ownedManyToManyRelations) {
-			relation.setMappedBy(this.configureFieldName(relation, relation.javaFieldNameFor(this)));
-		}
-	}
-
-	private void configureNonOwnedManyToManyFieldNames() {
-		for (ManyToManyRelation relation : this.nonOwnedManyToManyRelations) {
-			this.configureFieldName(relation, relation.javaFieldNameFor(this));
-		}
-	}
-
-	boolean foreignKeyColumnsContains(Column column) {
-		return this.foreignKeyColumns.contains(column);
-	}
-
-	boolean primaryKeyColumnsContains(Column column) {
-		return this.table.primaryKeyColumnsContains(column);
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/ManyToManyRelation.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/ManyToManyRelation.java
deleted file mode 100644
index d876087..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/ManyToManyRelation.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-import org.eclipse.jpt.db.internal.ForeignKey;
-
-/**
- * This object is shared by the two gen tables that make up the relation.
- * Upon construction, 'mappedBy' will be 'null'. The first gen table to be
- * used to generate an entity will fill in 'mappedBy' with the appropriate
- * field/property name.
- */
-class ManyToManyRelation {
-	private final GenTable joinTable;
-	private final ForeignKey owningForeignKey;
-	private final GenTable owningTable;
-	private final ForeignKey nonOwningForeignKey;
-	private final GenTable nonOwningTable;
-	private String mappedBy;
-
-
-	ManyToManyRelation(GenTable joinTable, ForeignKey owningForeignKey, GenTable owningTable, ForeignKey nonOwningForeignKey, GenTable nonOwningTable) {
-		super();
-		this.joinTable = joinTable;
-
-		this.owningForeignKey = owningForeignKey;
-		this.owningTable = owningTable;
-		owningTable.addOwnedManyToManyRelation(this);
-
-		this.nonOwningForeignKey = nonOwningForeignKey;
-		this.nonOwningTable = nonOwningTable;
-		nonOwningTable.addNonOwnedManyToManyRelation(this);
-	}
-
-	GenTable getJoinTable() {
-		return this.joinTable;
-	}
-
-	ForeignKey getOwningForeignKey() {
-		return this.owningForeignKey;
-	}
-
-	GenTable getOwningTable() {
-		return this.owningTable;
-	}
-
-	ForeignKey getNonOwningForeignKey() {
-		return this.nonOwningForeignKey;
-	}
-
-	GenTable getNonOwningTable() {
-		return this.nonOwningTable;
-	}
-
-	private GenTable otherTable(GenTable table) {
-		return (table == this.owningTable) ? this.nonOwningTable : this.owningTable;
-	}
-
-	String javaFieldNameFor(GenTable table) {
-		// TODO i18n?
-		return this.otherTable(table).javaFieldName() + "_collection";
-	}
-
-	void clear() {
-		this.owningTable.removeOwnedManyToManyRelation(this);
-		this.nonOwningTable.removeNonOwnedManyToManyRelation(this);
-	}
-
-	String getMappedBy() {
-		return this.mappedBy;
-	}
-
-	void setMappedBy(String mappedBy) {
-		this.mappedBy = mappedBy;
-	}
-
-	String owningEntityName() {
-		return this.owningTable.getEntityName();
-	}
-
-	String nonOwningEntityName() {
-		return this.nonOwningTable.getEntityName();
-	}
-
-	boolean joinTableNameIsDefault() {
-		return this.joinTable.name().equals(this.getOwningTable().name() + "_" + this.getNonOwningTable().name());
-	}
-
-	boolean joinColumnsIsDefaultFor(String javaFieldName) {
-		return this.owningForeignKey.isDefaultFor(javaFieldName);
-	}
-
-	boolean inverseJoinColumnsIsDefaultFor(String javaFieldName) {
-		return this.nonOwningForeignKey.isDefaultFor(javaFieldName);
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/ManyToOneRelation.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/ManyToOneRelation.java
deleted file mode 100644
index 333018d..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/ManyToOneRelation.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-import org.eclipse.jpt.db.internal.ForeignKey;
-
-class ManyToOneRelation {
-	private final GenTable baseTable;  // the "many" side
-	private final ForeignKey foreignKey;
-	private final GenTable referencedTable;  // the "one" side
-	private String mappedBy;
-
-
-	ManyToOneRelation(GenTable baseTable, ForeignKey foreignKey, GenTable referencedTable) {
-		super();
-		this.baseTable = baseTable;
-		this.foreignKey = foreignKey;
-		this.referencedTable = referencedTable;
-		referencedTable.addOneToManyRelation(new OneToManyRelation(this));
-	}
-
-	GenTable getBaseTable() {
-		return this.baseTable;
-	}
-
-	ForeignKey getForeignKey() {
-		return this.foreignKey;
-	}
-
-	GenTable getReferencedTable() {
-		return this.referencedTable;
-	}
-
-	String javaFieldName() {
-		return this.foreignKey.javaFieldName();
-	}
-
-	String getMappedBy() {
-		return this.mappedBy;
-	}
-
-	void setMappedBy(String mappedBy) {
-		this.mappedBy = mappedBy;
-	}
-
-	String baseEntityName() {
-		return this.baseTable.getEntityName();
-	}
-
-	String referencedEntityName() {
-		return this.referencedTable.getEntityName();
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/OneToManyRelation.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/OneToManyRelation.java
deleted file mode 100644
index 4656d00..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/OneToManyRelation.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-class OneToManyRelation {
-	private final ManyToOneRelation manyToOneRelation;
-
-	OneToManyRelation(ManyToOneRelation manyToOneRelation) {
-		super();
-		this.manyToOneRelation = manyToOneRelation;
-	}
-
-	ManyToOneRelation getManyToOneRelation() {
-		return this.manyToOneRelation;
-	}
-
-	String javaFieldName() {
-		// TODO i18n?
-		return this.manyToOneRelation.getBaseTable().javaFieldName() + "_collection";
-	}
-
-	String mappedBy() {
-		return this.manyToOneRelation.getMappedBy();
-	}
-
-	String referencedEntityName() {
-		return this.manyToOneRelation.baseEntityName();
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/PackageGenerator.java b/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/PackageGenerator.java
deleted file mode 100644
index eb74550..0000000
--- a/jpa/plugins/org.eclipse.jpt.gen/src/org/eclipse/jpt/gen/internal/PackageGenerator.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.gen.internal;
-
-import java.util.Collection;
-import java.util.Iterator;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jpt.db.internal.Table;
-import org.eclipse.jpt.gen.internal.EntityGenerator.OverwriteConfirmer;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-
-/**
- * This generator will generate a package of entities for a set of tables.
- */
-public class PackageGenerator {
-	private final Config config;
-	private final EntityGenerator.Config entityConfig;
-	private final GenScope scope;
-	private final OverwriteConfirmer overwriteConfirmer;
-	private final IProgressMonitor monitor;
-
-	// ********** public API **********
-
-	public static void generateEntities(Config config, EntityGenerator.Config entityConfig, Collection<Table> tables, OverwriteConfirmer overwriteConfirmer, IProgressMonitor monitor) {
-		if ((config == null) || (entityConfig == null) || (tables == null)) {
-			throw new NullPointerException();
-		}
-		try {
-			monitor.beginTask("", 1000);
-			new PackageGenerator(config, entityConfig, tables, overwriteConfirmer, monitor).generateEntities();
-		}
-		finally {
-			monitor.done();
-		}
-	}
-
-
-	// ********** construction/initialization **********
-
-	private PackageGenerator(Config config, EntityGenerator.Config entityConfig, Collection<Table> tables, OverwriteConfirmer overwriteConfirmer, IProgressMonitor monitor) {
-		super();
-		this.config = config;
-		this.entityConfig = entityConfig;
-		this.scope = new GenScope(tables, entityConfig, new SubProgressMonitor(monitor, 800));
-		this.overwriteConfirmer = overwriteConfirmer;
-		this.monitor = monitor;
-	}
-
-
-	// ********** generation **********
-
-	private void generateEntities() {
-		int size = this.scope.numEntityTables();
-		int ticks = 200/size;
-		for (Iterator<GenTable> stream = this.scope.entityTables(); stream.hasNext(); ) {
-			checkCanceled();
-			this.buildEntity(stream.next(), new SubProgressMonitor(this.monitor, ticks));
-		}
-	}
-
-	private void checkCanceled() {
-		if (this.monitor.isCanceled()) {
-			throw new OperationCanceledException();
-		}		
-	}
-	
-
-	private void buildEntity(GenTable genTable, IProgressMonitor monitor) {
-		EntityGenerator.generateEntity(this.entityConfig, this.config.getPackageFragment(), genTable, overwriteConfirmer, monitor);
-	}
-
-
-	// ********** config **********
-
-	public static class Config {
-		private IPackageFragment packageFragment;
-
-		public IPackageFragment getPackageFragment() {
-			return this.packageFragment;
-		}
-		public void setPackageFragment(IPackageFragment packageFragment) {
-			this.packageFragment = packageFragment;
-		}
-
-	}
-
-}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/.cvsignore b/jpa/plugins/org.eclipse.jpt.ui/.cvsignore
index ba077a4..a196dd7 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/.cvsignore
+++ b/jpa/plugins/org.eclipse.jpt.ui/.cvsignore
@@ -1 +1,6 @@
 bin
+@dot
+temp.folder
+build.xml
+javaCompiler...args
+javaCompiler...args.*
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
index 48b8ad8..1ff880b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
+++ b/jpa/plugins/org.eclipse.jpt.ui/property_files/jpt_ui.properties
@@ -77,5 +77,3 @@
 
 OverwriteConfirmerDialog_title=Overwrite Existing Class
 OverwriteConfirmerDialog_text=Overwrite source code for the class ''{0}''?
-
-EntitiesGenerator_jobName=Generating Entities
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatform.exsd b/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatform.exsd
index 6790dbe..92d1085 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatform.exsd
+++ b/jpa/plugins/org.eclipse.jpt.ui/schema/jpaPlatform.exsd
@@ -64,7 +64,7 @@
                   
                </documentation>
                <appInfo>
-                  <meta.attribute kind="java" basedOn="org.eclipse.jpt.ui.internal.IJpaPlatformUi"/>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jpt.ui.internal.IJpaPlatformUI"/>
                </appInfo>
             </annotation>
          </attribute>
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/AsynchronousUiCommandExecutor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/AsynchronousUiCommandExecutor.java
new file mode 100644
index 0000000..7dbc3c9
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/AsynchronousUiCommandExecutor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal;
+
+import org.eclipse.jpt.utility.internal.Command;
+import org.eclipse.jpt.utility.internal.CommandExecutor;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This implementation of CommandExecutor can be used by a non-UI
+ * thread to asynchronously modify a JPA project with any objects associated
+ * with documents that are currently displayed in the UI.
+ */
+public final class AsynchronousUiCommandExecutor
+	implements CommandExecutor
+{
+	public static final CommandExecutor INSTANCE = new AsynchronousUiCommandExecutor();
+
+	public static CommandExecutor instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private AsynchronousUiCommandExecutor() {
+		super();
+	}
+
+	public void execute(Command command) {
+		Display.getDefault().asyncExec(this.buildRunnable(command));
+	}
+
+	private Runnable buildRunnable(final Command command) {
+		return new Runnable() {
+			public void run() {
+				command.execute();
+			}
+		};
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaPlatformUi.java
index c53e5d8..9298773 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaPlatformUi.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaPlatformUi.java
@@ -11,59 +11,184 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jpt.core.internal.IJpaProject;
 import org.eclipse.jpt.ui.internal.details.IJpaDetailsProvider;
 import org.eclipse.jpt.ui.internal.generic.EntitiesGenerator;
+import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.details.ITypeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.java.details.JavaDetailsProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.BasicMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.DefaultBasicMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.DefaultEmbeddedMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddableUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedIdMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.EntityUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.IdMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToManyMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToOneMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.MappedSuperclassUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.NullTypeMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToManyMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToOneMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.TransientMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.VersionMappingUiProvider;
 import org.eclipse.jpt.ui.internal.java.structure.JavaStructureProvider;
 import org.eclipse.jpt.ui.internal.structure.IJpaStructureProvider;
 import org.eclipse.jpt.ui.internal.xml.details.XmlDetailsProvider;
 import org.eclipse.jpt.ui.internal.xml.structure.XmlStructureProvider;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
 
 public abstract class BaseJpaPlatformUi implements IJpaPlatformUi
 {
 	private Collection<IJpaDetailsProvider> detailsProviders;
 	private Collection<IJpaStructureProvider> structureProviders;
 	
+	private List<ITypeMappingUiProvider> javaTypeMappingUiProviders;
+	private List<IAttributeMappingUiProvider> javaAttributeMappingUiProviders;
+	private List<IAttributeMappingUiProvider> defaultJavaAttributeMappingUiProviders;
+	
+	private IJpaUiFactory jpaUiFactory;
+	
 	protected BaseJpaPlatformUi() {
 		super();
+		this.jpaUiFactory = createJpaUiFactory();
 	}
 
 	// ********** behavior **********
 	
-	public Collection<IJpaDetailsProvider> detailsProviders() {
+	protected abstract IJpaUiFactory createJpaUiFactory();
+
+	public IJpaUiFactory getJpaUiFactory() {
+		return this.jpaUiFactory;
+	}
+
+	public Iterator<IJpaDetailsProvider> detailsProviders() {
 		if (this.detailsProviders == null) {
-			this.detailsProviders = this.buildJpaDetailsProvider();
+			this.detailsProviders = new ArrayList<IJpaDetailsProvider>();
+			this.addDetailsProvidersTo(this.detailsProviders);
 		}
-		return this.detailsProviders;
-	}
-		
-	protected Collection<IJpaDetailsProvider> buildJpaDetailsProvider() {
-		Collection<IJpaDetailsProvider> detailsProviders = new ArrayList<IJpaDetailsProvider>();
-		detailsProviders.add(new JavaDetailsProvider());
-		detailsProviders.add(new XmlDetailsProvider());
-		return detailsProviders;
+		return new CloneIterator<IJpaDetailsProvider>(this.detailsProviders);
 	}
 	
-	public Collection<IJpaStructureProvider> structureProviders() {
+	/**
+	 * Override this to specify more or different details providers.
+	 * The default includes the JPA spec-defined java and orm.xml
+	 */
+	protected void addDetailsProvidersTo(Collection<IJpaDetailsProvider> providers) {
+		providers.add(new JavaDetailsProvider());
+		providers.add(new XmlDetailsProvider());
+	}
+	
+	public IJpaDetailsProvider detailsProvider(String fileContentType) {
+		for (Iterator<IJpaDetailsProvider> i = this.detailsProviders(); i.hasNext(); ) {
+			IJpaDetailsProvider provider = i.next();
+			if (provider.fileContentType().equals(fileContentType)) {
+				return provider;
+			}
+		}
+		return null;
+	}
+	
+	public Iterator<IJpaStructureProvider> structureProviders() {
 		if (this.structureProviders == null) {
-			this.structureProviders = this.buildJpaStructureProvider();
+			this.structureProviders = new ArrayList<IJpaStructureProvider>();
+			this.addStructureProvidersTo(this.structureProviders);
 		}
-		return this.structureProviders;
+		return new CloneIterator<IJpaStructureProvider>(this.structureProviders);
 	}
 	
-	protected Collection<IJpaStructureProvider> buildJpaStructureProvider() {
-		Collection<IJpaStructureProvider> structureProviders = new ArrayList<IJpaStructureProvider>();
-		structureProviders.add(new JavaStructureProvider());
-		structureProviders.add(new XmlStructureProvider());
-		return structureProviders;
+	/**
+	 * Override this to specify more or different structure providers.
+	 * The default includes the JPA spec-defined java and orm.xml
+	 */
+	protected void addStructureProvidersTo(Collection<IJpaStructureProvider> providers) {
+		providers.add(new JavaStructureProvider());
+		providers.add(new XmlStructureProvider());
 	}
 
+	public IJpaStructureProvider structureProvider(String fileContentType) {
+		for (Iterator<IJpaStructureProvider> i = this.structureProviders(); i.hasNext(); ) {
+			IJpaStructureProvider provider = i.next();
+			if (provider.fileContentType().equals(fileContentType)) {
+				return provider;
+			}
+		}
+		return null;
+	}
+	
+	public ListIterator<ITypeMappingUiProvider> javaTypeMappingUiProviders() {
+		if (this.javaTypeMappingUiProviders == null) {
+			this.javaTypeMappingUiProviders = new ArrayList<ITypeMappingUiProvider>();
+			this.addJavaTypeMappingUiProvidersTo(this.javaTypeMappingUiProviders);
+		}
+		return new CloneListIterator<ITypeMappingUiProvider>(this.javaTypeMappingUiProviders);
+	}
+	
+	/**
+	 * Override this to specify more or different type mapping ui providers
+	 * The default includes the JPA spec-defined entity, mapped superclass, embeddable,
+	 * and null (when the others don't apply)
+	 */
+	protected void addJavaTypeMappingUiProvidersTo(List<ITypeMappingUiProvider> providers) {
+		providers.add(NullTypeMappingUiProvider.instance());
+		providers.add(EntityUiProvider.instance());
+		providers.add(MappedSuperclassUiProvider.instance());			
+		providers.add(EmbeddableUiProvider.instance());			
+	}
+	
+	public ListIterator<IAttributeMappingUiProvider> javaAttributeMappingUiProviders() {
+		if (this.javaAttributeMappingUiProviders == null) {
+			this.javaAttributeMappingUiProviders = new ArrayList<IAttributeMappingUiProvider>();
+			this.addJavaAttributeMappingUiProvidersTo(this.javaAttributeMappingUiProviders);
+		}
+		return new CloneListIterator<IAttributeMappingUiProvider>(this.javaAttributeMappingUiProviders);
+
+	}
+	
+	/**
+	 * Override this to specify more or different java attribute mapping ui providers.
+	 * The default includes the JPA spec-defined basic, embedded, embeddedId, id, 
+	 * manyToMany, manyToOne, oneToMany, oneToOne, transient, and version
+	 */
+	protected void addJavaAttributeMappingUiProvidersTo(List<IAttributeMappingUiProvider> providers) {
+		providers.add(BasicMappingUiProvider.instance());
+		providers.add(EmbeddedMappingUiProvider.instance());
+		providers.add(EmbeddedIdMappingUiProvider.instance());
+		providers.add(IdMappingUiProvider.instance());			
+		providers.add(ManyToManyMappingUiProvider.instance());			
+		providers.add(ManyToOneMappingUiProvider.instance());			
+		providers.add(OneToManyMappingUiProvider.instance());			
+		providers.add(OneToOneMappingUiProvider.instance());
+		providers.add(TransientMappingUiProvider.instance());
+		providers.add(VersionMappingUiProvider.instance());
+	}
+	
+	public ListIterator<IAttributeMappingUiProvider> defaultJavaAttributeMappingUiProviders() {
+		if (this.defaultJavaAttributeMappingUiProviders == null) {
+			this.defaultJavaAttributeMappingUiProviders = new ArrayList<IAttributeMappingUiProvider>();
+			this.addDefaultJavaAttributeMappingUiProvidersTo(this.defaultJavaAttributeMappingUiProviders);
+		}
+		return new CloneListIterator<IAttributeMappingUiProvider>(this.defaultJavaAttributeMappingUiProviders);
+
+	}
+	
+	/**
+	 * Override this to specify more or different default java attribute mapping ui providers.
+	 * The default includes the JPA spec-defined basic, embedded
+	 */
+	protected void addDefaultJavaAttributeMappingUiProvidersTo(List<IAttributeMappingUiProvider> providers) {
+		providers.add(DefaultBasicMappingUiProvider.instance());
+		providers.add(DefaultEmbeddedMappingUiProvider.instance());
+	}
+
+
 	public void generateEntities(IJpaProject project, IStructuredSelection selection) {
-
 		EntitiesGenerator.generate(project, selection);
 	}
-	
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaUiFactory.java
new file mode 100644
index 0000000..b94a63b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/BaseJpaUiFactory.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal;
+
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.jpt.ui.internal.details.IJpaComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.BasicComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.EmbeddableComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.EmbeddedComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.EmbeddedIdComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.EntityComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.IdComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.ManyToManyComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.ManyToOneComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.MappedSuperclassComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.OneToManyComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.OneToOneComposite;
+import org.eclipse.jpt.ui.internal.mappings.details.TransientComposite;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+public abstract class BaseJpaUiFactory implements IJpaUiFactory
+{
+
+	public IJpaComposite createBasicMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new BasicComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createEmbeddableComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new EmbeddableComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createEmbeddedIdMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new EmbeddedIdComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createEmbeddedMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new EmbeddedComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createEntityComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new EntityComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createIdMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new IdComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createManyToManyMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new ManyToManyComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createManyToOneMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new ManyToOneComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createMappedSuperclassComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new MappedSuperclassComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createOneToManyMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new OneToManyComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createOneToOneMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new OneToOneComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createTransientMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new TransientComposite(parent, commandStack, widgetFactory);
+	}
+
+	public IJpaComposite createVersionMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return new BasicComposite(parent, commandStack, widgetFactory);
+
+	}
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/GenericJpaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/GenericJpaUiFactory.java
new file mode 100644
index 0000000..cd47ffe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/GenericJpaUiFactory.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal;
+
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.jpt.ui.internal.details.IJpaComposite;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+public class GenericJpaUiFactory extends BaseJpaUiFactory
+{
+	
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaPlatformUi.java
index b7fcb18..342ac51 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaPlatformUi.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaPlatformUi.java
@@ -9,19 +9,48 @@
  ******************************************************************************/
 package org.eclipse.jpt.ui.internal;
 
-import java.util.Collection;
-
+import java.util.Iterator;
+import java.util.ListIterator;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jpt.core.internal.IJpaProject;
 import org.eclipse.jpt.ui.internal.details.IJpaDetailsProvider;
+import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.details.ITypeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.structure.IJpaStructureProvider;
 
+
 public interface IJpaPlatformUi
 {
-	Collection<IJpaStructureProvider> structureProviders();
+	Iterator<IJpaStructureProvider> structureProviders();
 	
-	Collection<IJpaDetailsProvider> detailsProviders();
+	IJpaStructureProvider structureProvider(String fileContentType);
 	
+	Iterator<IJpaDetailsProvider> detailsProviders();
+	
+	IJpaDetailsProvider detailsProvider(String fileContentType);
+	
+	/**
+	 * Return the type mapping UI providers for java.  This will populate
+	 * the type mapping combo box in order and displaying ITypeMappingUiProvider.label().
+	 * It will also be used to create the appropriate composite given a type mapping. 
+	 */
+	ListIterator<ITypeMappingUiProvider> javaTypeMappingUiProviders();
+	
+	/**
+	 * Return the attribute mapping UI providers for java.  This will populate
+	 * the attribute mapping combo box in order and display IAttributeMappingUiProvider.label().
+	 * It will also be used to create the appropriate composite given an attribute mapping. 
+	 */
+	ListIterator<IAttributeMappingUiProvider> javaAttributeMappingUiProviders();
+
+	/**
+	 * Return the default attribute mapping UI providers for java.  These will be used
+	 * to provide a default mapping option if one applies in java.
+	 */
+	ListIterator<IAttributeMappingUiProvider> defaultJavaAttributeMappingUiProviders();
+
+	IJpaUiFactory getJpaUiFactory();
+
 	void generateDDL(IJpaProject project, IStructuredSelection selection);
 	
 	void generateEntities(IJpaProject project, IStructuredSelection selection);
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaUiFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaUiFactory.java
new file mode 100644
index 0000000..a66e18f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/IJpaUiFactory.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0, which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal;
+
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaBasic;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbeddable;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbedded;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEmbeddedId;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaEntity;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaId;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaManyToMany;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaManyToOne;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaMappedSuperclass;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaOneToMany;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaOneToOne;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaTransient;
+import org.eclipse.jpt.core.internal.content.java.mappings.IJavaVersion;
+import org.eclipse.jpt.core.internal.jdtutility.Attribute;
+import org.eclipse.jpt.core.internal.jdtutility.Type;
+import org.eclipse.jpt.ui.internal.details.IJpaComposite;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * Use IJpaFactory to create any IJavaTypeMapping or IJavaAttributeMappings.  This is necessary
+ * so that platforms can extend the java model with their own annotations. 
+ * IJavaTypeMappingProvider and IJavaAttributeMappingProvider use this factory.
+ * See IJpaPlatform.javaTypeMappingProviders() and IJpaPlatform.javaAttributeMappingProviders()
+ * for creating new mappings types.
+ * @see BaseJpaUiFactory
+ */
+public interface IJpaUiFactory
+{
+	IJpaComposite createEntityComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createEmbeddableComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createMappedSuperclassComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createBasicMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createEmbeddedMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createEmbeddedIdMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createIdMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createManyToManyMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createManyToOneMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createOneToManyMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createOneToOneMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createTransientMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+	
+	IJpaComposite createVersionMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java
index ff6bc50..cdc142e 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/JptUiMessages.java
@@ -144,7 +144,6 @@
 
 	public static String OverwriteConfirmerDialog_text;
 
-	public static String EntitiesGenerator_jobName;
 	
 	private JptUiMessages() {
 		throw new UnsupportedOperationException();
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/PlatformRegistry.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/PlatformRegistry.java
index ad616f2..ede93c3 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/PlatformRegistry.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/PlatformRegistry.java
@@ -23,8 +23,16 @@
 
 public class PlatformRegistry 
 {
-	public static final PlatformRegistry INSTANCE = new PlatformRegistry();
-	
+	// singleton
+	private static final PlatformRegistry INSTANCE = new PlatformRegistry();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static PlatformRegistry instance() {
+		return INSTANCE;
+	}
+
 	private static final String EXTENSION_ID = 
 		"jpaPlatform"; //$NON-NLS-1$
 	
@@ -52,8 +60,8 @@
 	private void buildJpaPlatforms() {
 		this.jpaPlatforms = new HashMap<String, IConfigurationElement>();
 		
-		for (Iterator stream = allConfigElements(); stream.hasNext(); ) {
-			buildJpaPlatform((IConfigurationElement) stream.next());
+		for (Iterator<IConfigurationElement> stream = allConfigElements(); stream.hasNext(); ) {
+			buildJpaPlatform(stream.next());
 		}
 	}
 	
@@ -75,16 +83,16 @@
 			return;
 		}
 		
-		if (jpaPlatforms.containsKey(platformId)) {
-			IConfigurationElement otherConfigElement = jpaPlatforms.get(platformId);
+		if (this.jpaPlatforms.containsKey(platformId)) {
+			IConfigurationElement otherConfigElement = this.jpaPlatforms.get(platformId);
 			reportDuplicatePlatform(configElement, otherConfigElement);
 		}
 		
-		jpaPlatforms.put(platformId, configElement);
+		this.jpaPlatforms.put(platformId, configElement);
 	}
 	
-	public IJpaPlatformUi getJpaPlatform(String vendorId) {
-		IConfigurationElement registeredConfigElement = this.jpaPlatforms.get(vendorId);
+	public IJpaPlatformUi jpaPlatform(String platformId) {
+		IConfigurationElement registeredConfigElement = this.jpaPlatforms.get(platformId);
 		
 		if (registeredConfigElement == null) {
 			return null;
@@ -99,17 +107,17 @@
 		}
 	}
 	
-	private Iterator allConfigElements() {
+	private Iterator<IConfigurationElement> allConfigElements() {
 		IExtensionRegistry registry = Platform.getExtensionRegistry();
 		IExtensionPoint extensionPoint = 
 			registry.getExtensionPoint(JptUiPlugin.PLUGIN_ID, EXTENSION_ID);
 		IExtension[] extensions = extensionPoint.getExtensions();
 		
-		return new CompositeIterator(
-				new TransformationIterator(CollectionTools.iterator(extensions)) {
+		return new CompositeIterator<IConfigurationElement>(
+				new TransformationIterator<IExtension, Iterator<IConfigurationElement>>(CollectionTools.iterator(extensions)) {
 					@Override
-					protected Object transform(Object next) {
-						return CollectionTools.iterator(((IExtension) next).getConfigurationElements());
+					protected Iterator<IConfigurationElement> transform(IExtension extension) {
+						return CollectionTools.iterator(extension.getConfigurationElements());
 					}
 				}
 			);
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/SynchronousUiCommandExecutor.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/SynchronousUiCommandExecutor.java
new file mode 100644
index 0000000..9ff5a25
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/SynchronousUiCommandExecutor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.ui.internal;
+
+import org.eclipse.jpt.utility.internal.Command;
+import org.eclipse.jpt.utility.internal.CommandExecutor;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This implementation of CommandExecutor can be used by a non-UI
+ * thread to synchronously modify a JPA project with any objects associated
+ * with documents that are currently displayed in the UI.
+ */
+public final class SynchronousUiCommandExecutor
+	implements CommandExecutor
+{
+	public static final CommandExecutor INSTANCE = new SynchronousUiCommandExecutor();
+
+	public static CommandExecutor instance() {
+		return INSTANCE;
+	}
+
+	// ensure single instance
+	private SynchronousUiCommandExecutor() {
+		super();
+	}
+
+	public void execute(Command command) {
+		Display.getDefault().syncExec(this.buildRunnable(command));
+	}
+
+	private Runnable buildRunnable(final Command command) {
+		return new Runnable() {
+			public void run() {
+				command.execute();
+			}
+		};
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/AddPersistentAttributeToXmlAndMapAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/AddPersistentAttributeToXmlAndMapAction.java
index d75a96d..f8ee745 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/AddPersistentAttributeToXmlAndMapAction.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/AddPersistentAttributeToXmlAndMapAction.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.actions;
 
 import org.eclipse.jface.action.IAction;
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java
index ab7a410..74143e1 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateDDLAction.java
@@ -10,8 +10,6 @@
 package org.eclipse.jpt.ui.internal.actions;
 
 import org.eclipse.jpt.core.internal.IJpaProject;
-import org.eclipse.jpt.ui.internal.IJpaPlatformUi;
-import org.eclipse.jpt.ui.internal.PlatformRegistry;
 
 /**
  *  GenerateDDLAction
@@ -23,13 +21,6 @@
 	}
 
 	protected void execute(IJpaProject project) {
-        String vendorId = project.getPlatform().getId();
-		
-        this.jpaPlatformUI(vendorId).generateDDL(project, this.getCurrentSelection());
+        this.jpaPlatformUi(project).generateDDL(project, this.getCurrentSelection());
 	}
-	
-	private IJpaPlatformUi jpaPlatformUI(String vendorId) {
-        return PlatformRegistry.INSTANCE.getJpaPlatform(vendorId); 
-	}
-
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java
index b125791..a6db0ca 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/GenerateEntitiesAction.java
@@ -10,8 +10,6 @@
 package org.eclipse.jpt.ui.internal.actions;
 
 import org.eclipse.jpt.core.internal.IJpaProject;
-import org.eclipse.jpt.ui.internal.IJpaPlatformUi;
-import org.eclipse.jpt.ui.internal.PlatformRegistry;
 
 /**
  *  GenerateEntitiesAction
@@ -22,13 +20,6 @@
 	}
 
 	protected void execute(IJpaProject project) {
-        String vendorId = project.getPlatform().getId();
-		
-        this.jpaPlatformUI(vendorId).generateEntities(project, this.getCurrentSelection());
+        this.jpaPlatformUi(project).generateEntities(project, this.getCurrentSelection());
 	}
-	
-	private IJpaPlatformUi jpaPlatformUI(String vendorId) {
-        return PlatformRegistry.INSTANCE.getJpaPlatform(vendorId); 
-	}
-
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/PersistentAttributeActionFilter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/PersistentAttributeActionFilter.java
index 2e6396f..f807a80 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/PersistentAttributeActionFilter.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/PersistentAttributeActionFilter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.actions;
 
 import org.eclipse.core.runtime.IAdapterFactory;
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java
index 04e657e..c728da0 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/ProjectAction.java
@@ -17,6 +17,8 @@
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jpt.core.internal.IJpaProject;
 import org.eclipse.jpt.core.internal.JptCorePlugin;
+import org.eclipse.jpt.ui.internal.IJpaPlatformUi;
+import org.eclipse.jpt.ui.internal.PlatformRegistry;
 import org.eclipse.ui.IActionDelegate;
 import org.eclipse.ui.IObjectActionDelegate;
 import org.eclipse.ui.IWorkbenchPart;
@@ -82,6 +84,11 @@
 		return null;
 	}
 
+	protected IJpaPlatformUi jpaPlatformUi(IJpaProject project) {
+		String coreJpaPlatformId = project.getPlatform().getId();
+        return PlatformRegistry.instance().jpaPlatform(coreJpaPlatformId); 
+	}
+	
 	protected void execute(IProject project) {
 		IJpaProject jpaProject = JptCorePlugin.getJpaProject(project);
 		if (jpaProject == null) {
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/XmlPersistentAttributeActionFilter.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/XmlPersistentAttributeActionFilter.java
index e5f57a9..736953b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/XmlPersistentAttributeActionFilter.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/actions/XmlPersistentAttributeActionFilter.java
@@ -1,3 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.actions;
 
 import org.eclipse.core.runtime.IAdapterFactory;
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJpaController.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJpaController.java
index e4401eb..84ac1dc 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJpaController.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/BaseJpaController.java
@@ -16,6 +16,8 @@
 
 public abstract class BaseJpaController 
 {
+	//****** we are using this commandStack in 0 places ********
+	//do we plan to use it in the future? *should* we be using it? are we removing emf?
 	protected CommandStack commandStack;
 	
 	protected TabbedPropertySheetWidgetFactory widgetFactory;
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java
index fb2a312..068840f 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentAttributeDetailsPage.java
@@ -9,10 +9,8 @@
  ******************************************************************************/
 package org.eclipse.jpt.ui.internal.details;
 
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.ListIterator;
 import java.util.Map;
 import org.eclipse.emf.common.command.BasicCommandStack;
 import org.eclipse.emf.common.notify.Adapter;
@@ -30,22 +28,13 @@
 import org.eclipse.jpt.core.internal.IJpaContentNode;
 import org.eclipse.jpt.core.internal.IPersistentAttribute;
 import org.eclipse.jpt.core.internal.JpaCorePackage;
+import org.eclipse.jpt.ui.internal.IJpaPlatformUi;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.JptUiMessages;
+import org.eclipse.jpt.ui.internal.PlatformRegistry;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.BasicMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.DefaultBasicMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.DefaultEmbeddedMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedIdMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.IdMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToManyMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToOneMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.NullAttributeMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToManyMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToOneMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.TransientMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.VersionMappingUiProvider;
 import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
+import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.widgets.Composite;
@@ -59,7 +48,6 @@
 	private IPersistentAttribute attribute;
 	private IAttributeMapping attributeMapping;
 	private Adapter persistentAttributeListener;
-	private Adapter attributeMappingListener;
 	
 	private String currentMappingKey;
 	
@@ -67,79 +55,38 @@
 	
 	private Map<String, IJpaComposite<IAttributeMapping>> mappingComposites;
 	protected PageBook mappingPageBook;	
-	private IJpaComposite<IAttributeMapping> currentMappingComposite;
-	
-	/**
-	 * These IAtttributeMappingUiProviders will be used as elements in the attributeMapping combo
-	 * The first element in the combo will be one of the defaultAttributemappingUiProviders or
-	 * if none of those apply the nullAttriubteMappingUiProvider will be used. The rest of the elements
-	 * will be the attributeMappingUiProviders.  The defaultAttributeMappingUiProvider is
-	 * determined by matching its key with the key of the current attriubteMapping.  
-	 */
-	private Collection<IAttributeMappingUiProvider> attributeMappingUiProviders;
-	private Collection<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders;
-	private IAttributeMappingUiProvider nullAttributeMappingUiProvider;
+	private IJpaComposite<IAttributeMapping> currentMappingComposite;	
 	
 	public PersistentAttributeDetailsPage(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
 		super(parent, SWT.NONE, new BasicCommandStack(), widgetFactory);
-		persistentAttributeListener = buildAttributeListener();
-		attributeMappingListener = buildAttributeMappingListener();
-		mappingComposites = new HashMap<String, IJpaComposite<IAttributeMapping>>();
-		this.attributeMappingUiProviders = buildAttributeMappingUiProviders();
-		this.defaultAttributeMappingUiProviders = buildDefaultAttributeMappingUiProviders();
-		this.nullAttributeMappingUiProvider = buildNullAttributeMappingUiProvider();
+		this.persistentAttributeListener = buildAttributeListener();
+		this.mappingComposites = new HashMap<String, IJpaComposite<IAttributeMapping>>();
 	}
 	
-	protected IAttributeMappingUiProvider buildNullAttributeMappingUiProvider() {
-		return NullAttributeMappingUiProvider.instance();
+	protected IJpaPlatformUi jpaPlatformUi() {
+		String platformId = getAttribute().jpaPlatform().getId();
+		return PlatformRegistry.instance().jpaPlatform(platformId);
+	}
+
+	protected IJpaUiFactory jpaUiFactory() {
+		return jpaPlatformUi().getJpaUiFactory();
 	}
 	
-	protected Collection<IAttributeMappingUiProvider> buildAttributeMappingUiProviders() {
-		Collection<IAttributeMappingUiProvider> providers = new ArrayList<IAttributeMappingUiProvider>();
-		providers.add(BasicMappingUiProvider.instance());
-		providers.add(EmbeddedMappingUiProvider.instance());
-		providers.add(EmbeddedIdMappingUiProvider.instance());
-		providers.add(IdMappingUiProvider.instance());			
-		providers.add(ManyToManyMappingUiProvider.instance());			
-		providers.add(ManyToOneMappingUiProvider.instance());			
-		providers.add(OneToManyMappingUiProvider.instance());			
-		providers.add(OneToOneMappingUiProvider.instance());
-		providers.add(TransientMappingUiProvider.instance());
-		providers.add(VersionMappingUiProvider.instance());
-		return providers;
-	}
+	protected abstract ListIterator<IAttributeMappingUiProvider> attributeMappingUiProviders();
 	
-	protected  Collection<IAttributeMappingUiProvider> attributeMappingUiProviders() {
-		return this.attributeMappingUiProviders;
-	}
-	
-	protected Collection<IAttributeMappingUiProvider> buildDefaultAttributeMappingUiProviders() {
-		Collection<IAttributeMappingUiProvider> providers = new ArrayList<IAttributeMappingUiProvider>();
-		providers.add(DefaultBasicMappingUiProvider.instance());		
-		providers.add(DefaultEmbeddedMappingUiProvider.instance());		
-		return providers;
-	}
-	
-	protected  Collection<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders() {
-		return this.defaultAttributeMappingUiProviders;
-	}
-	
-	private IAttributeMappingUiProvider attributeMappingUiProvider(String key) {
-		for (IAttributeMappingUiProvider provider : attributeMappingUiProviders()) {
-			if (provider.key() == key) {
+	protected abstract ListIterator<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders();
+		
+	protected IAttributeMappingUiProvider attributeMappingUiProvider(String key) {
+		for (ListIterator<IAttributeMappingUiProvider> i = attributeMappingUiProviders(); i.hasNext(); ) {
+			IAttributeMappingUiProvider provider = i.next();
+			if (provider.attributeMappingKey() == key) {
 				return provider;
 			}
 		}
-		return this.nullAttributeMappingUiProvider;
+		throw new IllegalArgumentException("Unsupported attribute mapping UI provider key: ");
 	}
-	private IAttributeMappingUiProvider defaultAttributeMappingUiProvider(String key) {
-		for (IAttributeMappingUiProvider provider : defaultAttributeMappingUiProviders()) {
-			if (provider.key() == key) {
-				return provider;
-			}
-		}
-		return this.nullAttributeMappingUiProvider;
-	}
+	
+	protected abstract IAttributeMappingUiProvider defaultAttributeMappingUiProvider(String key);
 	
 	private Adapter buildAttributeListener() {
 		return new AdapterImpl() {
@@ -150,7 +97,7 @@
 		};
 	}
 	
-	void persistentAttributeChanged(Notification notification) {
+	protected void persistentAttributeChanged(Notification notification) {
 		switch (notification.getFeatureID(IPersistentAttribute.class)) {
 			case JpaCorePackage.IPERSISTENT_ATTRIBUTE__MAPPING:
 				Display.getDefault().asyncExec(
@@ -162,28 +109,6 @@
 				break;
 		}
 	}
-	
-	private Adapter buildAttributeMappingListener() {
-		return new AdapterImpl() {
-			@Override
-			public void notifyChanged(Notification notification) {
-				attributeMappingChanged(notification);
-			}
-		};
-	}
-	
-	void attributeMappingChanged(Notification notification) {
-//		switch (notification.getFeatureID(IAttributeMapping.class)) {
-//			case JpaCorePackage.IATTRIBUTE_MAPPING__DEFAULT:
-//				Display.getDefault().asyncExec(
-//					new Runnable() {
-//						public void run() {
-//							populate();
-//						}
-//					});
-//				break;
-//		}
-	}
 		
 	protected Label buildMappingLabel(Composite parent) {
 		return getWidgetFactory().createLabel(parent, JptUiMessages.PersistentAttributePage_mapAs);
@@ -191,15 +116,15 @@
 	
 	protected CComboViewer buildMappingCombo(Composite parent) {
 		CCombo combo = getWidgetFactory().createCCombo(parent);
-		mappingCombo = new CComboViewer(combo);
-		mappingCombo.setContentProvider(buildContentProvider());
-		mappingCombo.setLabelProvider(buildLabelProvider());
-		mappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
+		this.mappingCombo = new CComboViewer(combo);
+		this.mappingCombo.setContentProvider(buildContentProvider());
+		this.mappingCombo.setLabelProvider(buildLabelProvider());
+		this.mappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
 			public void selectionChanged(SelectionChangedEvent event) {
 				mappingChanged(event);
 			}
 		});
-		return mappingCombo;
+		return this.mappingCombo;
 	}
 
 	private IContentProvider buildContentProvider() {
@@ -212,7 +137,7 @@
 				if (inputElement == null) {
 					return new Object[]{};
 				}
-				return uiProvidersFor((IPersistentAttribute) inputElement);
+				return attributeMappingUiProvidersFor((IPersistentAttribute) inputElement);
 			}
 			
 			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
@@ -221,22 +146,8 @@
 		};
 	}
 	
-	protected IAttributeMappingUiProvider[] uiProvidersFor(IPersistentAttribute persistentAttribute) {
-		IAttributeMappingUiProvider[] providers = new IAttributeMappingUiProvider[attributeMappingUiProviders().size() +1];
-		providers[0] =  this.nullAttributeMappingUiProvider;
-		for (IAttributeMappingUiProvider uiProvider : defaultAttributeMappingUiProviders()) {
-			if (uiProvider.key() == persistentAttribute.defaultMappingKey()) {
-				providers[0] = uiProvider;
-				break;
-			}
-		}
-		int i = 1;
-		for (IAttributeMappingUiProvider uiProvider : attributeMappingUiProviders()) {
-			providers[i++] = uiProvider;
-		}
-		return providers;
-	}
-
+	protected abstract IAttributeMappingUiProvider[] attributeMappingUiProvidersFor(IPersistentAttribute persistentAttribute);
+	
 	private IBaseLabelProvider buildLabelProvider() {
 		return new LabelProvider() {
 			@Override
@@ -247,16 +158,16 @@
 	}
 	
 	protected PageBook buildMappingPageBook(Composite parent) {
-		mappingPageBook = new PageBook(parent, SWT.NONE);
-		return mappingPageBook;
+		this.mappingPageBook = new PageBook(parent, SWT.NONE);
+		return this.mappingPageBook;
 	}
 	
 	protected IJpaComposite<IAttributeMapping> buildMappingComposite(PageBook pageBook, String key) {
 		if (this.attributeMapping == null || this.attributeMapping.isDefault()) {
-			return defaultAttributeMappingUiProvider(key).buildAttributeMappingComposite(pageBook, this.commandStack, getWidgetFactory());
+			return defaultAttributeMappingUiProvider(key).buildAttributeMappingComposite(jpaUiFactory(), pageBook, this.commandStack, getWidgetFactory());
 		}
 
-		return attributeMappingUiProvider(key).buildAttributeMappingComposite(pageBook, this.commandStack, getWidgetFactory());
+		return attributeMappingUiProvider(key).buildAttributeMappingComposite(jpaUiFactory(), pageBook, this.commandStack, getWidgetFactory());
 	}
 		
 	void mappingChanged(SelectionChangedEvent event) {
@@ -265,14 +176,14 @@
 		}
 		if (event.getSelection() instanceof StructuredSelection) {
 			IAttributeMappingUiProvider provider = (IAttributeMappingUiProvider) ((StructuredSelection) event.getSelection()).getFirstElement();
-			String key = (this.defaultAttributeMappingUiProviders().contains(provider) ? null : provider.key());
-			attribute.setSpecifiedMappingKey(key);
+			String key = (CollectionTools.contains(defaultAttributeMappingUiProviders(), provider) ? null : provider.attributeMappingKey());
+			this.attribute.setSpecifiedMappingKey(key);
 		}
 	}
 	
 	@Override
 	protected void doPopulate(IJpaContentNode persistentAttributeNode) {
-		attribute = (IPersistentAttribute) persistentAttributeNode;
+		this.attribute = (IPersistentAttribute) persistentAttributeNode;
 		populateMappingComboAndPage();
 	}
 	
@@ -283,92 +194,86 @@
 	
 	@Override
 	protected void engageListeners() {
-		if (attribute != null) {
-			attribute.eAdapters().add(persistentAttributeListener);
-			if (attributeMapping != null) {
-				attributeMapping.eAdapters().add(attributeMappingListener);
-			}
+		if (this.attribute != null) {
+			this.attribute.eAdapters().add(this.persistentAttributeListener);
 		}
 	}
 	
 	@Override
 	protected void disengageListeners() {
-		if (attribute != null) {
-			attribute.eAdapters().remove(persistentAttributeListener);
-			if (attributeMapping != null) {
-				attributeMapping.eAdapters().remove(attributeMappingListener);
-			}
+		if (this.attribute != null) {
+			this.attribute.eAdapters().remove(this.persistentAttributeListener);
 		}
 	}
 	
 	private void populateMappingComboAndPage() {
-		if (attribute == null) {
-			attributeMapping = null;
-			currentMappingKey = null;
-			mappingCombo.setInput(null);
-			mappingCombo.setSelection(StructuredSelection.EMPTY);
+		if (this.attribute == null) {
+			this.attributeMapping = null;
+			this.currentMappingKey = null;
+			this.mappingCombo.setInput(null);
+			this.mappingCombo.setSelection(StructuredSelection.EMPTY);
 			
-			if (currentMappingComposite != null) {
-				currentMappingComposite.populate(null);
-				currentMappingComposite = null;
+			if (this.currentMappingComposite != null) {
+				this.currentMappingComposite.populate(null);
+				this.currentMappingComposite = null;
 			}
 			
 			return;
 		}
-		attributeMapping = attribute.getMapping();
-		setComboData(attribute.candidateMappingKeys());
+		this.attributeMapping = this.attribute.getMapping();
+		setComboData();
 		
-		populateMappingPage(attributeMapping == null ? null : attributeMapping.getKey());
+		populateMappingPage(this.attributeMapping == null ? null : this.attributeMapping.getKey());
 	}
 	
 	private void populateMappingPage(String mappingKey) {
-		if (currentMappingComposite != null) {
-			if (mappingKey == currentMappingKey) {
-				if (currentMappingComposite != null) {
-					currentMappingComposite.populate(attributeMapping);
+		if (this.currentMappingComposite != null) {
+			if (mappingKey == this.currentMappingKey) {
+				if (this.currentMappingComposite != null) {
+					this.currentMappingComposite.populate(this.attributeMapping);
 					return;
 				}
 			}
 			else {
-				currentMappingComposite.populate(null);
+				this.currentMappingComposite.populate(null);
 				// don't return
 			}
 		}
 		
-		currentMappingKey = mappingKey;
+		this.currentMappingKey = mappingKey;
 		
 		IJpaComposite<IAttributeMapping> composite = mappingCompositeFor(mappingKey);
-		mappingPageBook.showPage(composite.getControl());
+		this.mappingPageBook.showPage(composite.getControl());
 		
-		currentMappingComposite = composite;
-		currentMappingComposite.populate(attributeMapping);
+		this.currentMappingComposite = composite;
+		this.currentMappingComposite.populate(this.attributeMapping);
 	}
 	
-	private void setComboData(Iterator<String> availableMappingKeys) {
-		if (attribute != mappingCombo.getInput()) {
-			mappingCombo.setInput(attribute);
+	private void setComboData() {
+		if (this.attribute != this.mappingCombo.getInput()) {
+			this.mappingCombo.setInput(this.attribute);
 		}
-		if (attributeMapping == null || attributeMapping.isDefault()) {
-			mappingCombo.setSelection(new StructuredSelection(mappingCombo.getElementAt(0)));
+		if (this.attributeMapping == null || this.attributeMapping.isDefault()) {
+			this.mappingCombo.setSelection(new StructuredSelection(this.mappingCombo.getElementAt(0)));
 		}
 		else {
-			IAttributeMappingUiProvider provider = attributeMappingUiProvider(attribute.mappingKey());
-			if (provider != null && ! provider.equals(((StructuredSelection) mappingCombo.getSelection()).getFirstElement())) {
-				mappingCombo.setSelection(new StructuredSelection(provider));
+			IAttributeMappingUiProvider provider = attributeMappingUiProvider(this.attribute.mappingKey());
+			if (provider != null && ! provider.equals(((StructuredSelection) this.mappingCombo.getSelection()).getFirstElement())) {
+				this.mappingCombo.setSelection(new StructuredSelection(provider));
 			}
 		}
 	}
 	
 	private IJpaComposite<IAttributeMapping> mappingCompositeFor(String key) {
-		IJpaComposite<IAttributeMapping> composite = mappingComposites.get(key);
+		IJpaComposite<IAttributeMapping> composite = this.mappingComposites.get(key);
 		if (composite != null) {
 			return composite;
 		}
 		
-		composite = buildMappingComposite(mappingPageBook, key);
+		composite = buildMappingComposite(this.mappingPageBook, key);
 		
 		if (composite != null) {
-			mappingComposites.put(key, composite);
+			this.mappingComposites.put(key, composite);
 		}
 		
 		return composite;
@@ -383,15 +288,13 @@
 	@Override
 	public void dispose() {
 		disengageListeners();
-		for (Iterator<IJpaComposite<IAttributeMapping>> stream = mappingComposites.values().iterator(); stream.hasNext(); ) {
-			stream.next().dispose();
+		for (IJpaComposite<IAttributeMapping> composite : this.mappingComposites.values()) {
+			composite.dispose();
 		}
 		super.dispose();
 	}
 	
 	public IPersistentAttribute getAttribute() {
-		return attribute;
+		return this.attribute;
 	}
-	
-
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java
index bd8353b..88b58c1 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/details/PersistentTypeDetailsPage.java
@@ -8,10 +8,9 @@
  ******************************************************************************/        
 package org.eclipse.jpt.ui.internal.details;
 
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.ListIterator;
 import java.util.Map;
 import org.eclipse.emf.common.command.BasicCommandStack;
 import org.eclipse.emf.common.notify.Adapter;
@@ -26,16 +25,13 @@
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jpt.core.internal.IJpaContentNode;
-import org.eclipse.jpt.core.internal.IJpaProject;
 import org.eclipse.jpt.core.internal.IPersistentType;
+import org.eclipse.jpt.core.internal.ITypeMapping;
 import org.eclipse.jpt.core.internal.JpaCorePackage;
 import org.eclipse.jpt.ui.internal.JptUiMessages;
 import org.eclipse.jpt.ui.internal.java.details.ITypeMappingUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddableUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.EntityUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.MappedSuperclassUiProvider;
-import org.eclipse.jpt.ui.internal.java.mappings.properties.NullTypeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
+import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.widgets.Composite;
@@ -53,33 +49,30 @@
 	
 	private CComboViewer typeMappingCombo;
 	
-	/**
-	 * A Map of mapping Composites of type IPersistenceComposite that is keyed on IConfigurationElement
-	 */
-	private Map composites;
+	private Map<String, IJpaComposite<ITypeMapping>> composites;
 	
 	protected PageBook typeMappingPageBook;
 	
-	private IJpaComposite visibleMappingComposite;
-	
-	private Collection<ITypeMappingUiProvider> typeMappingUiProviders;
+	private IJpaComposite<ITypeMapping> visibleMappingComposite;
 	
 	public PersistentTypeDetailsPage(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
 		super(parent, SWT.NONE, new BasicCommandStack(), widgetFactory);
 		this.persistentTypeListener = buildPersistentTypeListener();
-		this.composites = new HashMap();
-		this.typeMappingUiProviders = buildTypeMappingUiProviders();
+		this.composites = new HashMap<String, IJpaComposite<ITypeMapping>>();
 	}
 	
-	protected Collection<ITypeMappingUiProvider> buildTypeMappingUiProviders() {
-		Collection<ITypeMappingUiProvider> typeMappingUiProviders = new ArrayList<ITypeMappingUiProvider>();
-		typeMappingUiProviders.add(new NullTypeMappingUiProvider());
-		typeMappingUiProviders.add(new EntityUiProvider());
-		typeMappingUiProviders.add(new MappedSuperclassUiProvider());			
-		typeMappingUiProviders.add(new EmbeddableUiProvider());			
-		return typeMappingUiProviders;
-	}
+	protected abstract ListIterator<ITypeMappingUiProvider> typeMappingUiProviders();
 	
+	private ITypeMappingUiProvider typeMappingUiProvider(String key) {
+		for (ListIterator<ITypeMappingUiProvider> i = this.typeMappingUiProviders(); i.hasNext();) {
+			ITypeMappingUiProvider provider = i.next();
+			if (provider.mappingKey() == key) {
+				return provider;
+			}
+		}
+		throw new IllegalArgumentException("Unsupported type mapping UI provider key: " + key);
+	}
+
 	private Adapter buildPersistentTypeListener() {
 		return new AdapterImpl() {
 			public void notifyChanged(Notification notification) {
@@ -107,15 +100,15 @@
 	
 	protected CComboViewer buildTypeMappingCombo(Composite parent) {
 		CCombo combo = getWidgetFactory().createCCombo(parent);
-		typeMappingCombo = new CComboViewer(combo);
-		typeMappingCombo.setContentProvider(buildContentProvider());
-		typeMappingCombo.setLabelProvider(buildLabelProvider());
-		typeMappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
+		this.typeMappingCombo = new CComboViewer(combo);
+		this.typeMappingCombo.setContentProvider(buildContentProvider());
+		this.typeMappingCombo.setLabelProvider(buildLabelProvider());
+		this.typeMappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
 			public void selectionChanged(SelectionChangedEvent event) {
 				typeMappingChanged(event);
 			}
 		});
-		return typeMappingCombo;
+		return this.typeMappingCombo;
 	}
 	
 	private IContentProvider buildContentProvider() {
@@ -127,7 +120,7 @@
 			public Object[] getElements(Object inputElement) {
 				return (persistentType == null) ?
 						new String[] {}:
-						PersistentTypeDetailsPage.this.typeMappingUiProviders.toArray();
+						CollectionTools.array(PersistentTypeDetailsPage.this.typeMappingUiProviders());
 			}
 			
 			public void inputChanged(
@@ -146,22 +139,10 @@
 	}
 	
 	protected PageBook buildTypeMappingPageBook(Composite parent) {
-		typeMappingPageBook = new PageBook(parent, SWT.NONE);
-		return typeMappingPageBook;
+		this.typeMappingPageBook = new PageBook(parent, SWT.NONE);
+		return this.typeMappingPageBook;
 	}
-		
-	private IJpaProject getJpaProject() {
-		return getPersistentType().getJpaProject();
-	}
-
-	private ITypeMappingUiProvider typeMappingUiProvider(String key) {
-		for (ITypeMappingUiProvider provider : this.typeMappingUiProviders) {
-			if (provider.key() == key) {
-				return provider;
-			}
-		}
-		throw new IllegalArgumentException("unsupported type mapping UI provider key: " + key);
-	}
+	
 	
 	private void typeMappingChanged(SelectionChangedEvent event) {
 		if (isPopulating()) {
@@ -169,13 +150,13 @@
 		}
 		if (event.getSelection() instanceof StructuredSelection) {
 			ITypeMappingUiProvider provider = (ITypeMappingUiProvider) ((StructuredSelection) event.getSelection()).getFirstElement();
-			persistentType.setMappingKey(provider.key());
+			this.persistentType.setMappingKey(provider.mappingKey());
 		}
 	}
 	
 	@Override
 	protected void doPopulate(IJpaContentNode persistentTypeNode) {
-		persistentType = (IPersistentType) persistentTypeNode;
+		this.persistentType = (IPersistentType) persistentTypeNode;
 		populateMappingComboAndPage();
 	}
 	
@@ -185,90 +166,88 @@
 	}
 	
 	protected void engageListeners() {
-		if (persistentType != null) {
-			persistentType.eAdapters().add(persistentTypeListener);
+		if (this.persistentType != null) {
+			this.persistentType.eAdapters().add(this.persistentTypeListener);
 		}
 	}
 	
 	protected void disengageListeners() {
-		if (persistentType != null) {
-			persistentType.eAdapters().remove(persistentTypeListener);
+		if (this.persistentType != null) {
+			this.persistentType.eAdapters().remove(this.persistentTypeListener);
 		}
 	}
 	
 	private void populateMappingComboAndPage() {
-		if (persistentType == null) {
-			currentMappingKey = null;
-			typeMappingCombo.setInput(null);
-			typeMappingCombo.setSelection(StructuredSelection.EMPTY);
+		if (this.persistentType == null) {
+			this.currentMappingKey = null;
+			this.typeMappingCombo.setInput(null);
+			this.typeMappingCombo.setSelection(StructuredSelection.EMPTY);
 			
-			if (visibleMappingComposite != null) {
-				visibleMappingComposite.populate(null);
-				visibleMappingComposite = null;
+			if (this.visibleMappingComposite != null) {
+				this.visibleMappingComposite.populate(null);
+				this.visibleMappingComposite = null;
 			}
 			
 			return;
 		}
 		
-		String mappingKey = persistentType.getMapping().getKey();
-		setComboData(mappingKey, persistentType.candidateMappingKeys());
+		String mappingKey = this.persistentType.getMapping().getKey();
+		setComboData(mappingKey);
 		
 		populateMappingPage(mappingKey);
 	}
 	
 	private void populateMappingPage(String mappingKey) {
-		if (visibleMappingComposite != null) {
-			if (mappingKey  == currentMappingKey) {
-				if (visibleMappingComposite != null) {
-					visibleMappingComposite.populate(persistentType.getMapping());
+		if (this.visibleMappingComposite != null) {
+			if (mappingKey  == this.currentMappingKey) {
+				if (this.visibleMappingComposite != null) {
+					this.visibleMappingComposite.populate(this.persistentType.getMapping());
 					return;
 				}
 			}
 			else {
-				visibleMappingComposite.populate(null);
+				this.visibleMappingComposite.populate(null);
 				// don't return
 			}
 		}
 		
-		currentMappingKey = mappingKey;
+		this.currentMappingKey = mappingKey;
 		
 		IJpaComposite mappingComposite = mappingCompositeFor(mappingKey);
-		typeMappingPageBook.showPage(mappingComposite.getControl());
+		this.typeMappingPageBook.showPage(mappingComposite.getControl());
 		
-		visibleMappingComposite = mappingComposite;
-		visibleMappingComposite.populate(persistentType.getMapping());
+		this.visibleMappingComposite = mappingComposite;
+		this.visibleMappingComposite.populate(this.persistentType.getMapping());
 	}
 	
-	private void setComboData(String mappingKey, Iterator availableMappingKeys) {
-		if (persistentType != typeMappingCombo.getInput()) {
-			typeMappingCombo.setInput(persistentType);
+	private void setComboData(String mappingKey) {
+		if (this.persistentType != this.typeMappingCombo.getInput()) {
+			this.typeMappingCombo.setInput(this.persistentType);
 		}
 		
 		ITypeMappingUiProvider provider = typeMappingUiProvider(mappingKey);
-		if (! provider.equals(((StructuredSelection) typeMappingCombo.getSelection()).getFirstElement())) {
-			typeMappingCombo.setSelection(new StructuredSelection(provider));
+		if (! provider.equals(((StructuredSelection) this.typeMappingCombo.getSelection()).getFirstElement())) {
+			this.typeMappingCombo.setSelection(new StructuredSelection(provider));
 		}
 	}
 	
-	private IJpaComposite mappingCompositeFor(String key) {
-		IJpaComposite mappingComposite = (IJpaComposite) composites.get(key);
+	private IJpaComposite<ITypeMapping> mappingCompositeFor(String key) {
+		IJpaComposite<ITypeMapping> mappingComposite = this.composites.get(key);
 		if (mappingComposite != null) {
 			return mappingComposite;
 		}
 		
-		mappingComposite = buildMappingComposite(typeMappingPageBook, key);
+		mappingComposite = buildMappingComposite(this.typeMappingPageBook, key);
 		
 		if (mappingComposite != null) {
-			composites.put(key, mappingComposite);
+			this.composites.put(key, mappingComposite);
 		}
 		
 		return mappingComposite;
 	}
 	
-	protected IJpaComposite buildMappingComposite(PageBook pageBook, String key)  {
-		//TODO what about null composite?
+	protected IJpaComposite<ITypeMapping> buildMappingComposite(PageBook pageBook, String key)  {
 		return typeMappingUiProvider(key).buildPersistentTypeMappingComposite(pageBook, this.commandStack, getWidgetFactory());
-//		return new NullComposite(pageBook, commandStack);
 	}
 
 //TODO focus??
@@ -279,14 +258,14 @@
 	
 	public void dispose() {
 		disengageListeners();
-		for (Iterator i = composites.values().iterator(); i.hasNext(); ) {
-			((IJpaComposite) i.next()).dispose();
+		for (Iterator<IJpaComposite<ITypeMapping>> i = this.composites.values().iterator(); i.hasNext(); ) {
+			i.next().dispose();
 		}
 		super.dispose();
 	}
 	
 	public IPersistentType getPersistentType() {
-		return persistentType;
+		return this.persistentType;
 	}
 
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java
index 21c7550..6c6ab4e 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentAttributeToXmlAndMapDialog.java
@@ -160,7 +160,7 @@
 	
 	public String getMappingKey() {
 		StructuredSelection selection = (StructuredSelection) mappingCombo.getSelection();
-		return (selection.isEmpty()) ? null : ((IAttributeMappingUiProvider) selection.getFirstElement()).key();
+		return (selection.isEmpty()) ? null : ((IAttributeMappingUiProvider) selection.getFirstElement()).attributeMappingKey();
 	}
 	
 	private void validate() {
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java
index 1bd955b..836f0d3 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/dialogs/AddPersistentClassDialog.java
@@ -116,9 +116,9 @@
 				
 				public Object[] getElements(Object inputElement) {
 					return new Object[] {
-						new MappedSuperclassUiProvider(), 
-						new EntityUiProvider(), 
-						new EmbeddableUiProvider()
+						MappedSuperclassUiProvider.instance(), 
+						EntityUiProvider.instance(), 
+						EmbeddableUiProvider.instance()
 					};
 				}
 				
@@ -195,7 +195,7 @@
 	
 	public String getMappingKey() {
 		StructuredSelection selection = (StructuredSelection) mappingCombo.getSelection();
-		return (selection.isEmpty()) ? null : ((ITypeMappingUiProvider) selection.getFirstElement()).key();
+		return (selection.isEmpty()) ? null : ((ITypeMappingUiProvider) selection.getFirstElement()).mappingKey();
 	}
 	
 	protected IType chooseType() {
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/EntitiesGenerator.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/EntitiesGenerator.java
index 300861c..ee8cbe0 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/EntitiesGenerator.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/EntitiesGenerator.java
@@ -9,6 +9,7 @@
 *******************************************************************************/
 package org.eclipse.jpt.ui.internal.generic;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.Collection;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.resources.WorkspaceJob;
@@ -17,8 +18,10 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.window.Window;
 import org.eclipse.jface.wizard.WizardDialog;
@@ -38,6 +41,9 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.progress.IProgressService;
 
 /**
  *  EntitiesGenerator
@@ -110,7 +116,7 @@
 				IJpaProject project,
 				EntityGenerator.OverwriteConfirmer overwriteConfirmer
 		) {
-			super(JptUiMessages.EntitiesGenerator_jobName);
+			super("Generating Entities");
 			this.packageConfig = packageConfig;
 			this.entityConfig = entityConfig;
 			this.selectedTables = selectedTables;
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/GenericPlatformUi.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/GenericPlatformUi.java
index 0189ea6..1490e5f 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/GenericPlatformUi.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/generic/GenericPlatformUi.java
@@ -10,11 +10,12 @@
 package org.eclipse.jpt.ui.internal.generic;
 
 import java.text.MessageFormat;
-
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jpt.core.internal.IJpaProject;
 import org.eclipse.jpt.ui.internal.BaseJpaPlatformUi;
+import org.eclipse.jpt.ui.internal.GenericJpaUiFactory;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.JptUiMessages;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
@@ -25,6 +26,11 @@
 		super();
 	}
 	
+	@Override
+	protected IJpaUiFactory createJpaUiFactory() {
+		return new GenericJpaUiFactory();
+	}
+	
 	public void generateDDL(IJpaProject project, IStructuredSelection selection) {
 		this.displayNotSupportedMessage(JptUiMessages.GenericPlatformUiDialog_notSupportedMessageTitle, JptUiMessages.GenericPlatformUiDialog_notSupportedMessageText);
 	}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/IAttributeMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/IAttributeMappingUiProvider.java
index 4276feb..4493c0c 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/IAttributeMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/IAttributeMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IAttributeMapping;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
@@ -22,7 +23,7 @@
 	 * A unique string that corresponds to the key of a MappingProvider in the core
 	 * (IJavaAttributeMappingProvider and/or IXmlAttributeMappingProvider)
 	 */
-	String key();
+	String attributeMappingKey();
 
 	/**
 	 * A label to be displayed to the label as an option in the mapping type combo box 
@@ -34,13 +35,14 @@
 	 * The IJpaComposite that correponds to this mapping type.  This will be displayed
 	 * by the PersistentAttributeDetailsPage when the mapping key matches the key given
 	 * by this provider.  The composites will be stored in a Map with the mapping key as the key.
-	 * 
+	 * @param factory
 	 * @param parent
 	 * @param commandStack
 	 * @param widgetFactory
+	 * 
 	 * @return
 	 */
 	IJpaComposite<IAttributeMapping> buildAttributeMappingComposite(
-			Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
+			IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
 	
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/ITypeMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/ITypeMappingUiProvider.java
index d614a57..51318e9 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/ITypeMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/ITypeMappingUiProvider.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.ui.internal.java.details;
 
 import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.jpt.core.internal.ITypeMapping;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
@@ -19,7 +20,7 @@
 	/**
 	 * A unique string that corresponds to the key of a MappingProvider in the core
 	 */
-	String key();
+	String mappingKey();
 	
 	/**
 	 * A label to be displayed to the label as an option in the mapping type combo box 
@@ -37,7 +38,7 @@
 	 * @param widgetFactory
 	 * @return
 	 */
-	IJpaComposite buildPersistentTypeMappingComposite(
+	IJpaComposite<ITypeMapping> buildPersistentTypeMappingComposite(
 			Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory);
 	
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentAttributeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentAttributeDetailsPage.java
index b249b9b..9853600 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentAttributeDetailsPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentAttributeDetailsPage.java
@@ -9,8 +9,12 @@
  ******************************************************************************/
 package org.eclipse.jpt.ui.internal.java.details;
 
+import java.util.ListIterator;
+import org.eclipse.jpt.core.internal.IPersistentAttribute;
 import org.eclipse.jpt.ui.internal.details.PersistentAttributeDetailsPage;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.NullAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
+import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -25,6 +29,51 @@
 		super(parent, widgetFactory);
 	}
 	
+	
+	@Override
+	protected ListIterator<IAttributeMappingUiProvider> attributeMappingUiProviders() {
+		return jpaPlatformUi().javaAttributeMappingUiProviders();
+	}
+	
+	protected IAttributeMappingUiProvider nullAttributeMappingUiProvider() {
+		return NullAttributeMappingUiProvider.instance();
+	}
+
+	@Override
+	protected ListIterator<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders() {
+		return jpaPlatformUi().defaultJavaAttributeMappingUiProviders();
+	}
+
+
+	/**
+	 * These IAtttributeMappingUiProviders will be used as elements in the attributeMapping combo
+	 * The first element in the combo will be one of the defaultAttributeMappingUiProviders or
+	 * if none of those apply the nullAttributeMappingUiProvider will be used. The rest of the elements
+	 * will be the attributeMappingUiProviders.  The defaultAttributeMappingUiProvider is
+	 * determined by matching its key with the key of the current attributeMapping.  
+	 */
+	@Override
+	protected IAttributeMappingUiProvider[] attributeMappingUiProvidersFor(IPersistentAttribute persistentAttribute) {
+		IAttributeMappingUiProvider[] providers = new IAttributeMappingUiProvider[CollectionTools.size(attributeMappingUiProviders()) + 1];
+		providers[0] =  defaultAttributeMappingUiProvider(persistentAttribute.defaultMappingKey());
+		int i = 1;
+		for (ListIterator<IAttributeMappingUiProvider> iterator = attributeMappingUiProviders(); iterator.hasNext(); ) {
+			providers[i++] = iterator.next();
+		}
+		return providers;
+	}
+	
+	@Override
+	protected IAttributeMappingUiProvider defaultAttributeMappingUiProvider(String key) {
+		for (ListIterator<IAttributeMappingUiProvider> i = defaultAttributeMappingUiProviders(); i.hasNext(); ) {
+			IAttributeMappingUiProvider provider = i.next();
+			if (provider.attributeMappingKey() == key) {
+				return provider;
+			}
+		}
+		return this.nullAttributeMappingUiProvider();
+	}
+	
 	@Override
 	protected void initializeLayout(Composite composite) {
 		composite.setLayout(new GridLayout(2, false));
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentTypeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentTypeDetailsPage.java
index 9b2d273..c795b37 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentTypeDetailsPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/details/JavaPersistentTypeDetailsPage.java
@@ -9,6 +9,9 @@
  ******************************************************************************/
 package org.eclipse.jpt.ui.internal.java.details;
 
+import java.util.ListIterator;
+import org.eclipse.jpt.ui.internal.IJpaPlatformUi;
+import org.eclipse.jpt.ui.internal.PlatformRegistry;
 import org.eclipse.jpt.ui.internal.details.PersistentTypeDetailsPage;
 import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
 import org.eclipse.swt.SWT;
@@ -26,6 +29,16 @@
 		super(parent, widgetFactory);
 	}
 	
+	protected IJpaPlatformUi jpaPlatformUi() {
+		String platformId = getPersistentType().jpaPlatform().getId();
+		return PlatformRegistry.instance().jpaPlatform(platformId);
+	}
+	
+	@Override
+	protected ListIterator<ITypeMappingUiProvider> typeMappingUiProviders() {
+		return jpaPlatformUi().javaTypeMappingUiProviders();
+	}
+
 	@Override
 	protected void initializeLayout(Composite composite) {	    
 	    GridLayout gridLayout = new GridLayout();
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/BasicMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/BasicMappingUiProvider.java
index 72af6c5..b1a3ce7 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/BasicMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/BasicMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -39,7 +40,7 @@
 		super();
 	}
 	
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -47,7 +48,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_BasicLabel;
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new BasicComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createBasicMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultBasicMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultBasicMappingUiProvider.java
index c01c35d..090752d 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultBasicMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultBasicMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -38,7 +39,7 @@
 		super();
 	}
 	
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -46,7 +47,7 @@
 		return "Default (" + JptUiMappingsMessages.PersistentAttributePage_BasicLabel + ")";
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new BasicComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createBasicMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultEmbeddedMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultEmbeddedMappingUiProvider.java
index 57c4932..385150b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultEmbeddedMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/DefaultEmbeddedMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -38,7 +39,7 @@
 		super();
 	}
 	
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -46,7 +47,7 @@
 		return "Default (" + JptUiMappingsMessages.PersistentAttributePage_EmbeddedLabel + ")";
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new EmbeddedComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createEmbeddedMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddableUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddableUiProvider.java
index ca4a97e..b15444d 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddableUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddableUiProvider.java
@@ -20,7 +20,24 @@
 
 public class EmbeddableUiProvider implements ITypeMappingUiProvider
 {
-	public String key() {
+	// singleton
+	private static final EmbeddableUiProvider INSTANCE = new EmbeddableUiProvider();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static ITypeMappingUiProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private EmbeddableUiProvider() {
+		super();
+	}
+
+	public String mappingKey() {
 		return IMappingKeys.EMBEDDABLE_TYPE_MAPPING_KEY;
 	}
 	
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedIdMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedIdMappingUiProvider.java
index fb49af2..e80ad57 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedIdMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedIdMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -39,7 +40,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -47,7 +48,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_EmbeddedIdLabel;
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new EmbeddedIdComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createEmbeddedIdMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedMappingUiProvider.java
index 4da937b..0938a6b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EmbeddedMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -39,7 +40,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -47,7 +48,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_EmbeddedLabel;
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new EmbeddedComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createEmbeddedMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EntityUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EntityUiProvider.java
index 80d489a..64c4c2a 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EntityUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/EntityUiProvider.java
@@ -20,7 +20,24 @@
 
 public class EntityUiProvider implements ITypeMappingUiProvider
 {
-	public String key() {
+	// singleton
+	private static final EntityUiProvider INSTANCE = new EntityUiProvider();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static ITypeMappingUiProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private EntityUiProvider() {
+		super();
+	}
+
+	public String mappingKey() {
 		return IMappingKeys.ENTITY_TYPE_MAPPING_KEY;
 	}
 	
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/IdMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/IdMappingUiProvider.java
index 199b0fb..8dad497 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/IdMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/IdMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -38,7 +39,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.ID_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -46,7 +47,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_IdLabel;
 	}
 
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new IdComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createIdMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToManyMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToManyMappingUiProvider.java
index 8515d35..2cbfe6e 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToManyMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToManyMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -38,7 +39,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -46,7 +47,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_ManyToManyLabel;
 	}
 
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new ManyToManyComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createManyToManyMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToOneMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToOneMappingUiProvider.java
index c81832c..44e7050 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToOneMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/ManyToOneMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -38,7 +39,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -46,7 +47,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_ManyToOneLabel;
 	}
 
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new ManyToOneComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createManyToOneMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/MappedSuperclassUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/MappedSuperclassUiProvider.java
index aa71476..e15397c 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/MappedSuperclassUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/MappedSuperclassUiProvider.java
@@ -20,7 +20,24 @@
 
 public class MappedSuperclassUiProvider implements ITypeMappingUiProvider
 {
-	public String key() {
+	// singleton
+	private static final MappedSuperclassUiProvider INSTANCE = new MappedSuperclassUiProvider();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static ITypeMappingUiProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private MappedSuperclassUiProvider() {
+		super();
+	}
+
+	public String mappingKey() {
 		return IMappingKeys.MAPPED_SUPERCLASS_TYPE_MAPPING_KEY;
 	}
 	
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullAttributeMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullAttributeMappingUiProvider.java
index 1c16047..ca2907b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullAttributeMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullAttributeMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.swt.SWT;
@@ -40,7 +41,7 @@
 	}
 
 
-	public String key() {
+	public String attributeMappingKey() {
 		return null;
 	}
 	
@@ -48,7 +49,7 @@
 		return "";
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
 		return new NullComposite(parent);
 	}
 	
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullTypeMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullTypeMappingUiProvider.java
index b435bd5..1b44936 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullTypeMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/NullTypeMappingUiProvider.java
@@ -20,7 +20,24 @@
 
 public class NullTypeMappingUiProvider implements ITypeMappingUiProvider
 {
-	public String key() {
+	// singleton
+	private static final NullTypeMappingUiProvider INSTANCE = new NullTypeMappingUiProvider();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static ITypeMappingUiProvider instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullTypeMappingUiProvider() {
+		super();
+	}
+	
+	public String mappingKey() {
 		return null;
 	}
 	
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToManyMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToManyMappingUiProvider.java
index bb130bc..26c96c6 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToManyMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToManyMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -38,7 +39,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -46,7 +47,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_OneToManyLabel;
 	}
 
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new OneToManyComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createOneToManyMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToOneMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToOneMappingUiProvider.java
index 27fa225..9bd426d 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToOneMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/OneToOneMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -39,7 +40,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -47,7 +48,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_OneToOneLabel;
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new OneToOneComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createOneToOneMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/TransientMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/TransientMappingUiProvider.java
index c8b4811..e77742a 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/TransientMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/TransientMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -39,7 +40,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -47,7 +48,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_TransientLabel;
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new TransientComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createTransientMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/VersionMappingUiProvider.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/VersionMappingUiProvider.java
index 75f14df..de3dc66 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/VersionMappingUiProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/java/mappings/properties/VersionMappingUiProvider.java
@@ -11,6 +11,7 @@
 
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.jpt.core.internal.IMappingKeys;
+import org.eclipse.jpt.ui.internal.IJpaUiFactory;
 import org.eclipse.jpt.ui.internal.details.IJpaComposite;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
@@ -39,7 +40,7 @@
 		super();
 	}
 
-	public String key() {
+	public String attributeMappingKey() {
 		return IMappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY;
 	}
 	
@@ -47,7 +48,7 @@
 		return JptUiMappingsMessages.PersistentAttributePage_VersionLabel;
 	}
 	
-	public IJpaComposite buildAttributeMappingComposite(Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
-		return new VersionComposite(parent, commandStack, widgetFactory);
+	public IJpaComposite buildAttributeMappingComposite(IJpaUiFactory factory, Composite parent, CommandStack commandStack, TabbedPropertySheetWidgetFactory widgetFactory) {
+		return factory.createVersionMappingComposite(parent, commandStack, widgetFactory);
 	}
 }
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/CatalogCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/CatalogCombo.java
index c51d015..7d842e9 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/CatalogCombo.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/CatalogCombo.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.Iterator;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
@@ -17,7 +18,6 @@
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jpt.core.internal.mappings.ITable;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -70,11 +70,11 @@
 
 	private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 			// not interested to this event.
 			}
 
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -85,7 +85,7 @@
 				});
 			}
 
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -96,12 +96,12 @@
 				});
 			}
 
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -112,7 +112,7 @@
 				});
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				getControl().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (database == CatalogCombo.this.getDatabase()) {
@@ -124,11 +124,11 @@
 				});
 			}
 
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 			// not interested to this event.
 			}
 
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 			// not interested to this event.
 			}
 		};
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/ColumnComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/ColumnComposite.java
index 7502f79..3c55a65 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/ColumnComposite.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/ColumnComposite.java
@@ -9,19 +9,18 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.Iterator;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.notify.impl.AdapterImpl;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.impl.EObjectImpl;
-import org.eclipse.jpt.core.internal.IJpaProject;
 import org.eclipse.jpt.core.internal.mappings.DefaultTrueBoolean;
 import org.eclipse.jpt.core.internal.mappings.IAbstractColumn;
 import org.eclipse.jpt.core.internal.mappings.IColumn;
 import org.eclipse.jpt.core.internal.mappings.INamedColumn;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -79,11 +78,11 @@
     private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
 
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 				// not interested to this event.
 			}
 
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -94,7 +93,7 @@
 				});
 			}
 
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -105,12 +104,12 @@
 				});
 			}
 
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -121,15 +120,15 @@
 				});
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				return;
 			}
 
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				return;
 			}
 
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if(table == getDbTable()) {
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/InheritanceComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/InheritanceComposite.java
index deb6154..d0dc292 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/InheritanceComposite.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/InheritanceComposite.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.Iterator;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
@@ -28,7 +29,6 @@
 import org.eclipse.jpt.core.internal.mappings.INamedColumn;
 import org.eclipse.jpt.core.internal.mappings.InheritanceType;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -96,11 +96,11 @@
     private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
 
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 				// not interested to this event.
 			}
 
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -111,7 +111,7 @@
 				});
 			}
 
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -122,12 +122,12 @@
 				});
 			}
 
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -138,15 +138,15 @@
 				});
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				return;
 			}
 
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				return;
 			}
 
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if(table == getDbTable()) {
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/JoinTableComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/JoinTableComposite.java
index f5fd60c..1f2f436 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/JoinTableComposite.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/JoinTableComposite.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.List;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
@@ -21,7 +22,6 @@
 import org.eclipse.jpt.core.internal.mappings.IJoinColumn;
 import org.eclipse.jpt.core.internal.mappings.IJoinTable;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -31,7 +31,6 @@
 import org.eclipse.jpt.ui.internal.details.BaseJpaComposite;
 import org.eclipse.jpt.ui.internal.mappings.JptUiMappingsMessages;
 import org.eclipse.jpt.ui.internal.mappings.details.JoinColumnsComposite.Owner;
-import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
@@ -77,11 +76,11 @@
 	private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
 
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 				// not interested to this event.
 			}
 
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						JoinTableComposite.this.tableCombo.populate();
@@ -89,7 +88,7 @@
 				});
 			}
 
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						JoinTableComposite.this.tableCombo.populate();
@@ -97,12 +96,12 @@
 				});
 			}
 
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						JoinTableComposite.this.tableCombo.populate();
@@ -110,7 +109,7 @@
 				});
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if(database == JoinTableComposite.this.tableCombo.getDatabase()) {
@@ -122,7 +121,7 @@
 				});
 			}
 			
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				getControl().getDisplay().asyncExec( new Runnable() {
 					public void run() {
 						if(schema == JoinTableComposite.this.tableCombo.getTableSchema()) {
@@ -134,7 +133,7 @@
 				});
 			}
 
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 				// not interested to this event.
 			}
 		};
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/SchemaCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/SchemaCombo.java
index 9655c22..f5b11b3 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/SchemaCombo.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/SchemaCombo.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.Iterator;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
@@ -17,7 +18,6 @@
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jpt.core.internal.mappings.ITable;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -70,11 +70,11 @@
 
 	private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 			// not interested to this event.
 			}
 
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -85,7 +85,7 @@
 				});
 			}
 
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -96,12 +96,12 @@
 				});
 			}
 
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -112,7 +112,7 @@
 				});
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				getControl().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (database == SchemaCombo.this.getDatabase()) {
@@ -124,7 +124,7 @@
 				});
 			}
 
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				getControl().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (schema == SchemaCombo.this.getTableSchema()) {
@@ -136,7 +136,7 @@
 				});
 			}
 
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 			// not interested to this event.
 			}
 		};
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableCombo.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableCombo.java
index 3304743..68e148b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableCombo.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableCombo.java
@@ -9,6 +9,7 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.Iterator;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
@@ -16,7 +17,6 @@
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jpt.core.internal.mappings.ITable;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -68,11 +68,11 @@
 
 	private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 			// not interested to this event.
 			}
 
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -83,7 +83,7 @@
 				});
 			}
 
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -94,12 +94,12 @@
 				});
 			}
 
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				getCombo().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (getControl().isDisposed()) {
@@ -110,7 +110,7 @@
 				});
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				getControl().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (database == TableCombo.this.getDatabase()) {
@@ -122,7 +122,7 @@
 				});
 			}
 
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				getControl().getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (schema == TableCombo.this.getTableSchema()) {
@@ -134,7 +134,7 @@
 				});
 			}
 
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 			// not interested to this event.
 			}
 		};
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableGeneratorComposite.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableGeneratorComposite.java
index 4c2f937..7426882 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableGeneratorComposite.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/mappings/details/TableGeneratorComposite.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.ui.internal.mappings.details;
 
 import java.util.Iterator;
+
 import org.eclipse.emf.common.command.CommandStack;
 import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.ecore.EObject;
@@ -17,7 +18,6 @@
 import org.eclipse.jpt.core.internal.mappings.IId;
 import org.eclipse.jpt.core.internal.mappings.ITableGenerator;
 import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.Database;
@@ -485,23 +485,23 @@
 	
 	private ConnectionListener buildConnectionListener() {
 		return new ConnectionListener() {
-			public void closed(Connection connection) {
+			public void closed(ConnectionProfile profile) {
 				populate();
 			}
 			
-			public void modified(Connection connection) {
+			public void modified(ConnectionProfile profile) {
 				populate();
 			}
 
-			public void opened(Connection connection) {
+			public void opened(ConnectionProfile profile) {
 				populate();
 			}
 
-			public void databaseChanged(Connection connection, final Database database) {
+			public void databaseChanged(ConnectionProfile profile, final Database database) {
 				populate();
 			}
 			
-			public void schemaChanged(Connection connection, final Schema schema) {
+			public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				populate();
 			}
 
@@ -518,16 +518,16 @@
 				});
 			}
 			
-			public void aboutToClose(Connection connection) {
+			public void aboutToClose(ConnectionProfile profile) {
 				// not interested to this event.
 			}
 			
-			public boolean okToClose(Connection connection) {
+			public boolean okToClose(ConnectionProfile profile) {
 				// not interested to this event.
 				return true;
 			}
 			
-			public void tableChanged(Connection connection, final Table table) {
+			public void tableChanged(ConnectionProfile profile, final Table table) {
 				// not interested to this event.
 			}
 		};
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java
index 0089adf..4ae07a8 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/properties/JpaProjectPropertiesPage.java
@@ -204,7 +204,7 @@
 			platformCombo.setContentProvider(
 					new IStructuredContentProvider() {
 						public Object[] getElements(Object inputElement) {
-							return CollectionTools.array(JpaPlatformRegistry.INSTANCE.allJpaPlatformIds());
+							return CollectionTools.array(JpaPlatformRegistry.instance().allJpaPlatformIds());
 						}
 						
 						public void dispose() {}
@@ -219,7 +219,7 @@
 						}
 						
 						public String getText(Object element) {
-							return JpaPlatformRegistry.INSTANCE.getJpaPlatformLabel((String) element);
+							return JpaPlatformRegistry.instance().jpaPlatformLabel((String) element);
 						}
 						
 						public void addListener(ILabelProviderListener listener) {}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionManager.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionManager.java
index df7fd63..42e7dc2 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionManager.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionManager.java
@@ -1,11 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- * program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
  * 
- * Contributors: Oracle. - initial API and implementation
- *******************************************************************************/
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 import org.eclipse.ui.IWorkbenchPart;
@@ -42,4 +43,5 @@
 	 * part is closed.
 	 */
 	public void register(IWorkbenchPart part);	
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionParticipant.java
index 7657d00..56fdb85 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionParticipant.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/ISelectionParticipant.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- *  Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- *  program and the accompanying materials are made available under the terms of
- *  the Eclipse Public License v1.0 which accompanies this distribution, and is
- *  available at http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: Oracle. - initial API and implementation
- *  
- *******************************************************************************/
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 public interface ISelectionParticipant 
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java
index 9e84ab4..da44c1d 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaDetailsSelectionParticipant.java
@@ -1,41 +1,42 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- * program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
  * 
- * Contributors: Oracle. - initial API and implementation
- *******************************************************************************/
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 import org.eclipse.jpt.ui.internal.views.JpaDetailsView;
 
 
-public class JpaDetailsSelectionParticipant extends AbstractSelectionParticipant 
+public class JpaDetailsSelectionParticipant
+	implements ISelectionParticipant 
 {
-	private JpaDetailsView detailsView;
+	private final JpaDetailsView detailsView;
 	
 	
-	public JpaDetailsSelectionParticipant(
-				ISelectionManager theSelectionManager, JpaDetailsView view) {
-		super(theSelectionManager);
-		detailsView = view;
+	public JpaDetailsSelectionParticipant(JpaDetailsView detailsView) {
+		super();
+		this.detailsView = detailsView;
 	}
-	
-	
+
 	public Selection getSelection() {
-		return detailsView.getSelection();
+		return this.detailsView.getSelection();
 	}
 
 	public void selectionChanged(SelectionEvent evt) {
-		detailsView.select(evt.getSelection());
+		this.detailsView.select(evt.getSelection());
 	}
-	
+
 	public boolean disposeOnHide() {
 		return false;
 	}
-	
+
 	public void dispose() {
-		// no op
+		// NOP
 	}
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java
index bfa9499..749efdc 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/JpaStructureSelectionParticipant.java
@@ -1,56 +1,67 @@
 /*******************************************************************************
- *  Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- *  program and the accompanying materials are made available under the terms of
- *  the Eclipse Public License v1.0 which accompanies this distribution, and is
- *  available at http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: Oracle. - initial API and implementation
- *******************************************************************************/
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jpt.ui.internal.views.JpaStructureView;
 
-public class JpaStructureSelectionParticipant 
-	extends AbstractSelectionParticipant 
+public class JpaStructureSelectionParticipant
+	implements ISelectionParticipant 
 {
-	private JpaStructureView structureView;
-	
-	private ISelectionChangedListener structureViewListener;
+	final JpaStructureView structureView;
 	
 	
-	public JpaStructureSelectionParticipant(
-				ISelectionManager theSelectionManager, JpaStructureView theOutlineView) {
-		super(theSelectionManager);
-		structureView = theOutlineView;
-		structureViewListener = new StructureViewSelectionListener();
-		structureView.addSelectionChangedListener(structureViewListener);
+	public JpaStructureSelectionParticipant(ISelectionManager selectionManager, JpaStructureView structureView) {
+		super();
+		this.structureView = structureView;
+		structureView.addSelectionChangedListener(new StructureViewSelectionListener(selectionManager, structureView));
 	}
-	
-	
+
 	public Selection getSelection() {
-		return structureView.getSelection();
+		return this.structureView.getSelection();
 	}
 	
 	public void selectionChanged(SelectionEvent evt) {
-		structureView.select(evt.getSelection());
+		this.structureView.select(evt.getSelection());
 	}
-	
+
 	public boolean disposeOnHide() {
 		return false;
 	}
 	
 	public void dispose() {
-		// no op
+		// NOP
 	}
 	
-	
+
+	// ********** listener **********
+
 	private class StructureViewSelectionListener 
 		implements ISelectionChangedListener
 	{
-		public void selectionChanged(SelectionChangedEvent event) {
-			selectionManager.select(structureView.getSelection());
+		private final ISelectionManager selectionManager;
+
+		StructureViewSelectionListener(ISelectionManager selectionManager, JpaStructureView structureView) {
+			super();
+			this.selectionManager = selectionManager;
 		}
+
+		public void selectionChanged(SelectionChangedEvent event) {
+			this.selectionManager.select(this.structureViewSelection());
+		}
+
+		private Selection structureViewSelection() {
+			return JpaStructureSelectionParticipant.this.structureView.getSelection();
+		}
+
 	}
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/Selection.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/Selection.java
index c02d684..e05032b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/Selection.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/Selection.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- *  Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- *  program and the accompanying materials are made available under the terms of
- *  the Eclipse Public License v1.0 which accompanies this distribution, and is
- *  available at http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: Oracle. - initial API and implementation
- *  
- *******************************************************************************/
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 import org.eclipse.jpt.core.internal.IJpaContentNode;
@@ -20,51 +20,52 @@
 	
 	
 	/* Used internally - only for NULL_SELECTION */
-	private Selection() {}
+	private Selection() {
+		super();
+	}
 	
-	public Selection(IJpaContentNode node) {
-		if (node == null) {
-			throw new IllegalArgumentException("Must have non-null node.  Use NULL_SELECTION otherwise.");
+	public Selection(IJpaContentNode selectedNode) {
+		if (selectedNode == null) {
+			throw new NullPointerException("A 'selectedNode' is required; otherwise use NULL_SELECTION.");
 		}
-		
-		selectedNode = node;
+		this.selectedNode = selectedNode;
 	}
 	
 	public IJpaContentNode getSelectedNode() {
 		return selectedNode;
 	}
 	
+	@Override
 	public boolean equals(Object obj) {
 		if (! (obj instanceof Selection)) {
 			return false;
 		}
 		
-		if (this == NULL_SELECTION && obj == NULL_SELECTION) {
+		if ((this == NULL_SELECTION) && (obj == NULL_SELECTION)) {
 			return true;
 		}
 		
-		if (this == NULL_SELECTION || obj == NULL_SELECTION) {
+		if ((this == NULL_SELECTION) || (obj == NULL_SELECTION)) {
 			return false;
 		}
 		
 		return this.selectedNode.equals(((Selection) obj).selectedNode);
 	}
 	
+	@Override
 	public int hashCode() {
-		if (this == NULL_SELECTION) {
-			return super.hashCode();
-		}
-		else {
-			return this.selectedNode.hashCode();
-		}
+		return (this == NULL_SELECTION) ?
+			super.hashCode()
+		:
+			this.selectedNode.hashCode();
 	}
-	
+
+	@Override
 	public String toString() {
-		if (this == NULL_SELECTION) {
-			return "NULL_SELECTION";
-		}
-		else {
-			return selectedNode.toString();
-		}
+		return (this == NULL_SELECTION) ?
+			"NULL_SELECTION"
+		:
+			selectedNode.toString();
 	}
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManager.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManager.java
index e9af08d..108a700 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManager.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionManager.java
@@ -1,12 +1,12 @@
 /*******************************************************************************
- *  Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- *  program and the accompanying materials are made available under the terms of
- *  the Eclipse Public License v1.0 which accompanies this distribution, and is
- *  available at http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: Oracle. - initial API and implementation
- *  
- *******************************************************************************/
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 import java.util.Collections;
@@ -15,6 +15,7 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+
 import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IPageListener;
@@ -32,11 +33,11 @@
 	implements ISelectionManager
 {
 	/* The set of pages for which this object is managing selections */
-	private Set pages;
+	private Set<IWorkbenchPage> pages;
 	
 	/* The map of <code>ISelectionParticipant</code>s (keyed by part) this object
 	   is using to manage selections */
-	private Map selectionParticipants;
+	private Map<IWorkbenchPart, ISelectionParticipant> selectionParticipants;
 	
 	private IPageListener pageListener;
 	
@@ -50,8 +51,8 @@
 	
 	public SelectionManager() {
 		super();
-		pages = Collections.synchronizedSet(new HashSet());
-		selectionParticipants = Collections.synchronizedMap(new HashMap());
+		pages = Collections.synchronizedSet(new HashSet<IWorkbenchPage>());
+		selectionParticipants = Collections.synchronizedMap(new HashMap<IWorkbenchPart, ISelectionParticipant>());
 		pageListener = new PageListener();
 		partListener = new PartListener();
 		currentSelection = Selection.NULL_SELECTION;
@@ -63,7 +64,7 @@
 		initPage(aWindow.getActivePage());
 	}
 	
-	private void initPage(IWorkbenchPage page) {
+	void initPage(IWorkbenchPage page) {
 		if ((page != null) && (! pages.contains(page))) {
 			page.addPartListener(partListener);
 			pages.add(page);
@@ -73,14 +74,14 @@
 		}
 	}
 	
-	private void disposePage(IWorkbenchPage page) {
+	void disposePage(IWorkbenchPage page) {
 		if ((page != null) && (pages.contains(page))) {
 			page.removePartListener(partListener);
 			pages.remove(page);
 		}
 	}
 	
-	private void initPart(IWorkbenchPart part) {
+	void initPart(IWorkbenchPart part) {
 		if (part != null) {
 			if (selectionParticipants.get(part) == null) {
 				ISelectionParticipant selectionParticipant = 
@@ -92,21 +93,21 @@
 		}
 	}
 	
-	private void selectPart(IWorkbenchPart part) {
+	void selectPart(IWorkbenchPart part) {
 		ISelectionParticipant selectionParticipant = getSelectionParticipant(part);
 		if (selectionParticipant != null) {
 			select(selectionParticipant.getSelection());
 		}
 	}
 	
-	private void hidePart(IWorkbenchPart part) {
+	void hidePart(IWorkbenchPart part) {
 		ISelectionParticipant selectionParticipant = getSelectionParticipant(part);
 		if ((selectionParticipant != null) && (selectionParticipant.disposeOnHide())) {
 			closePart(part);
 		}
 	}
 	
-	private void closePart(IWorkbenchPart part) {
+	void closePart(IWorkbenchPart part) {
 		ISelectionParticipant selectionParticipant = getSelectionParticipant(part);
 		if (selectionParticipant != null) {
 			disposePart(part);
@@ -114,15 +115,13 @@
 		}
 	}
 	
-	private void disposePart(IWorkbenchPart part) {
+	void disposePart(IWorkbenchPart part) {
 		if ((part != null) && (selectionParticipants.containsKey(part))) {
-			ISelectionParticipant selectionParticipant = 
-				(ISelectionParticipant) selectionParticipants.remove(part);
-			selectionParticipant.dispose();
+			selectionParticipants.remove(part).dispose();
 		}
 	}
 	
-	private void checkForNoEditors() {
+	void checkForNoEditors() {
 		IWorkbenchPage activePage = window.getActivePage();
 		if ((activePage == null)
 				|| (activePage.getActiveEditor() == null)) {
@@ -174,13 +173,13 @@
 	}
 	
 	private void fireSelectionChange(SelectionEvent event) {
-		for (Iterator stream = selectionParticipants.values().iterator(); stream.hasNext(); ) {
-			((ISelectionParticipant) stream.next()).selectionChanged(event);
+		for (ISelectionParticipant sp : selectionParticipants.values()) {
+			sp.selectionChanged(event);
 		}
 	}
 	
 	private ISelectionParticipant getSelectionParticipant(IWorkbenchPart part) {
-		return (ISelectionParticipant) selectionParticipants.get(part);
+		return selectionParticipants.get(part);
 	}
 		
 	public Selection getCurrentSelection() {
@@ -191,61 +190,77 @@
 		window.removePageListener(pageListener);
 		selectionParticipants.clear();
 		
-		for (Iterator stream = new CloneIterator(pages); stream.hasNext(); ) {
-			disposePage((IWorkbenchPage) stream.next());
+		for (Iterator<IWorkbenchPage> stream = new CloneIterator<IWorkbenchPage>(this.pages); stream.hasNext(); ) {
+			this.disposePage(stream.next());
 		}
-		
-		for (Iterator stream = new CloneIterator(selectionParticipants.keySet()); stream.hasNext(); ) {
-			disposePart((IWorkbenchPart) stream.next());
+
+		for (Iterator<IWorkbenchPart> stream = new CloneIterator<IWorkbenchPart>(selectionParticipants.keySet()); stream.hasNext(); ) {
+			this.disposePart(stream.next());
 		}
 	}
 	
 	
 	private class PageListener implements IPageListener
 	{
-		public void pageActivated(IWorkbenchPage page) {}
+		public void pageActivated(IWorkbenchPage page) {
+			// nop
+		}
+		
+		PageListener() {
+			super();
+		}
 		
 		public void pageClosed(IWorkbenchPage page) {
-			disposePage(page);
+			SelectionManager.this.disposePage(page);
 		}
 		
 		public void pageOpened(IWorkbenchPage page) {
-			initPage(page);
+			SelectionManager.this.initPage(page);
 		}
 	}
 	
 	
 	private class PartListener implements IPartListener2
 	{
+		PartListener() {
+			super();
+		}
+		
 		public void partActivated(IWorkbenchPartReference partRef) {
 			IWorkbenchPart part = partRef.getPart(false);
 			if (part != null) {
-				initPart(part);
-				selectPart(part);
+				SelectionManager.this.initPart(part);
+				SelectionManager.this.selectPart(part);
 			}
 		}
 		
-		public void partBroughtToTop(IWorkbenchPartReference partRef) {}
+		public void partBroughtToTop(IWorkbenchPartReference partRef) {
+			// nop
+		}
 		
 		public void partClosed(IWorkbenchPartReference partRef) {
 			IWorkbenchPart part = partRef.getPart(false);
 			if (part != null) {
-				closePart(part);
-				disposePart(part);
-				checkForNoEditors();
+				SelectionManager.this.closePart(part);
+				SelectionManager.this.disposePart(part);
+				SelectionManager.this.checkForNoEditors();
 			}
 		}
 		
-		public void partDeactivated(IWorkbenchPartReference partRef) {}
+		public void partDeactivated(IWorkbenchPartReference partRef) {
+			// nop
+		}
 		
 		public void partHidden(IWorkbenchPartReference partRef) {
 			IWorkbenchPart part = partRef.getPart(false);
 			if (part != null) {
-				hidePart(part);
+				SelectionManager.this.hidePart(part);
 			}
 		}
 		
-		public void partInputChanged(IWorkbenchPartReference partRef) {}
+		public void partInputChanged(IWorkbenchPartReference partRef) {
+			// nop
+		}
 		
 		public void partOpened(IWorkbenchPartReference partRef) {
 			IWorkbenchPart part = partRef.getPart(false);
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionParticipantFactory.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionParticipantFactory.java
index 2c90739..0bd4ca3 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionParticipantFactory.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/SelectionParticipantFactory.java
@@ -1,11 +1,12 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- * program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
  * 
- * Contributors: Oracle. - initial API and implementation
- *******************************************************************************/
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
 import org.eclipse.core.runtime.IAdapterFactory;
@@ -17,7 +18,12 @@
 public class SelectionParticipantFactory 
 	implements IAdapterFactory
 {
-	/* @see IAdapterFactory#getAdapter(Object, Class) */
+	private static final Class[] ADAPTER_LIST = new Class[] { ISelectionParticipant.class };
+
+	public Class[] getAdapterList() {
+		return ADAPTER_LIST;
+	}
+
 	public Object getAdapter(Object adaptableObject, Class adapterType) {
 		if (! (adaptableObject instanceof IWorkbenchPart)) {
 			return null;
@@ -25,26 +31,19 @@
 		
 		ISelectionManager selectionManager = 
 			SelectionManagerFactory.getSelectionManager(((IWorkbenchPart) adaptableObject).getSite().getWorkbenchWindow());
-		// TODO - turn this into extension point
+		// TODO turn this into extension point
 		if (adaptableObject instanceof ITextEditor) {
-			return new TextEditorSelectionParticipant(
-							selectionManager, (ITextEditor) adaptableObject);
+			return new TextEditorSelectionParticipant(selectionManager, (ITextEditor) adaptableObject);
 		}
 		else if (adaptableObject instanceof JpaStructureView) {
-			return new JpaStructureSelectionParticipant(
-							selectionManager, (JpaStructureView) adaptableObject);
+			return new JpaStructureSelectionParticipant(selectionManager, (JpaStructureView) adaptableObject);
 		}
 		else if (adaptableObject instanceof JpaDetailsView) {
-			return new JpaDetailsSelectionParticipant(
-							selectionManager, (JpaDetailsView) adaptableObject);
+			return new JpaDetailsSelectionParticipant((JpaDetailsView) adaptableObject);
 		}
 		else {
 			return null;
 		}
 	}
-	
-	/* @see IAdapterFactory#getAdapterList() */
-	public Class[] getAdapterList() {
-		return new Class[] { ISelectionParticipant.class };
-	}
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
index 0c13777..74e2a8b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
@@ -1,14 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved. This
- * program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
+ * Copyright (c) 2006, 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
  * 
- * Contributors: Oracle. - initial API and implementation
- *******************************************************************************/
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
 package org.eclipse.jpt.ui.internal.selection;
 
-import org.eclipse.core.resources.IFile;
 import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.viewers.IPostSelectionProvider;
 import org.eclipse.jface.viewers.ISelection;
@@ -26,111 +26,52 @@
 import org.eclipse.ui.texteditor.ITextEditor;
 
 public class TextEditorSelectionParticipant 
-	extends AbstractSelectionParticipant 
+	implements ISelectionParticipant 
 {
-	private ITextEditor editor;
+	private final ISelectionManager selectionManager;
+
+	final ITextEditor textEditor;
 	
-	private IPropertyListener editorInputListener;
+	private final IPropertyListener editorInputListener;
 	
-	private ISelectionChangedListener editorSelectionListener;
+	private final ISelectionChangedListener editorSelectionListener;
 	
 	private Selection currentSelection;
 	
-	private boolean suppressNotification = false;
+	private boolean forwardSelection = true;  // TODO this just smells wrong  ~bjv
 	
 	
-	public TextEditorSelectionParticipant(ISelectionManager theSelectionManager, ITextEditor theEditor) {
-		super(theSelectionManager);
-		editor = theEditor;
-		editorInputListener = new EditorInputListener();
-		editor.addPropertyListener(editorInputListener);
-		editorSelectionListener = new EditorSelectionListener();
-		((IPostSelectionProvider) editor.getSelectionProvider()).addPostSelectionChangedListener(editorSelectionListener);
-		currentSelection = calculateSelection();
+	public TextEditorSelectionParticipant(ISelectionManager selectionManager, ITextEditor textEditor) {
+		super();
+		this.selectionManager = selectionManager;
+		this.textEditor = textEditor;
+		this.editorInputListener = new EditorInputListener();
+		this.textEditor.addPropertyListener(this.editorInputListener);
+		this.editorSelectionListener = new EditorSelectionListener();
+		this.postSelectionProvider().addPostSelectionChangedListener(this.editorSelectionListener);
+		this.currentSelection = this.calculateSelection();
 	}
-	
-	private void editorInputChanged() {
-		Selection newSelection = calculateSelection();
-		
-		if (! newSelection.equals(currentSelection)) {
-			currentSelection = newSelection;
-			
-			if (! suppressNotification) {
-				selectionManager.select(newSelection);
-			}
-		}
-	}
-	
-	private void editorSelectionChanged(SelectionChangedEvent event) {
-		Selection newSelection = calculateSelection();
-		
-		if (! newSelection.equals(currentSelection)) {
-			currentSelection = newSelection;
-			
-			// bug 188344 - won't actively change selection manager selection if 
-			// a "JPA" view is the active (and presumably selecting) view
-			if (editor.getEditorSite().getPage().getActivePart() instanceof AbstractJpaView) {
-				return;
-			}
-			
-			if (! suppressNotification) {
-				selectionManager.select(newSelection);
-			}
-		}
-	}
-	
-	private Selection calculateSelection() {
-		if (editor == null) {
-			return Selection.NULL_SELECTION;
-		}
-		
-		ISelection selection = editor.getSelectionProvider().getSelection();
-		IJpaFile persistenceFile = persistenceFileFor(editor.getEditorInput());
-		
-		if ((persistenceFile == null)
-			|| (! (selection instanceof ITextSelection))) {
-			return Selection.NULL_SELECTION;
-		}
-		
-		IJpaContentNode selectedNode = persistenceFile.getContentNode(((ITextSelection) selection).getOffset());
-		if (selectedNode == null) {
-			return Selection.NULL_SELECTION;
-		}
-		return new Selection(selectedNode);
-	}
-	
+
+	// ********** ISelectionParticipant implementation **********
+
 	public Selection getSelection() {
-		return currentSelection;
+		return this.currentSelection;
 	}
 	
-	public IJpaFile persistenceFileFor(IEditorInput input) {
-		IFile file = null;
-		if (input instanceof IFileEditorInput) {
-			IFileEditorInput fileInput = (IFileEditorInput) input;
-			file = fileInput.getFile();
-		}
-		if (file == null) {
-			return null;
-		}
-		return JptCorePlugin.getJpaFile(file);
-	}
-		
 	public void selectionChanged(SelectionEvent evt) {
 		Selection newSelection = evt.getSelection();
 		
-		if ((getSelection().equals(newSelection))
-			|| (newSelection == Selection.NULL_SELECTION)) {
+		if ((newSelection == Selection.NULL_SELECTION)
+			|| newSelection.equals(this.currentSelection)) {
 			return;
 		}
 		
-		suppressNotification = true;
-		IJpaContentNode selectedNode = newSelection.getSelectedNode();
-		
-		ITextRange textRange = selectedNode.selectionTextRange();
+		this.forwardSelection = false;
+		ITextRange textRange = newSelection.getSelectedNode().selectionTextRange();
 		if (textRange != null) {
-			this.editor.selectAndReveal(textRange.getOffset(), textRange.getLength());
+			this.textEditor.selectAndReveal(textRange.getOffset(), textRange.getLength());
 		}
-		suppressNotification = false;
+		this.forwardSelection = true;
 	}
 	
 	public boolean disposeOnHide() {
@@ -138,27 +79,99 @@
 	}
 	
 	public void dispose() {
-		this.editor.removePropertyListener(this.editorInputListener);
-		((IPostSelectionProvider) this.editor.getSelectionProvider()).removePostSelectionChangedListener(editorSelectionListener);
+		this.textEditor.removePropertyListener(this.editorInputListener);
+		this.postSelectionProvider().removePostSelectionChangedListener(this.editorSelectionListener);
+	}
+
+
+	// ********** internal methods **********
+
+	private Selection calculateSelection() {
+		ISelection selection = this.textEditor.getSelectionProvider().getSelection();
+		if (! (selection instanceof ITextSelection)) {
+			return Selection.NULL_SELECTION;
+		}
+
+		IJpaFile persistenceFile = this.persistenceFile();
+		if (persistenceFile == null) {
+			return Selection.NULL_SELECTION;
+		}
+
+		IJpaContentNode selectedNode = persistenceFile.getContentNode(((ITextSelection) selection).getOffset());
+		if (selectedNode == null) {
+			return Selection.NULL_SELECTION;
+		}
+
+		return new Selection(selectedNode);
 	}
 	
+	private IJpaFile persistenceFile() {
+		IEditorInput input = this.textEditor.getEditorInput();
+		if ( ! (input instanceof IFileEditorInput)) {
+			return null;
+		}
+		return JptCorePlugin.getJpaFile(((IFileEditorInput) input).getFile());
+	}
+		
+	private IPostSelectionProvider postSelectionProvider() {
+		return (IPostSelectionProvider) this.textEditor.getSelectionProvider();
+	}
+
+
+	// ********** listener callbacks **********
+
+	void editorInputChanged() {
+		Selection newSelection = this.calculateSelection();
+		if (newSelection.equals(this.currentSelection)) {
+			return;
+		}
+		this.currentSelection = newSelection;
+		if (this.forwardSelection) {
+			this.selectionManager.select(newSelection);
+		}
+	}
 	
-	private class EditorInputListener
-		implements IPropertyListener
-	{
+	void editorSelectionChanged(SelectionChangedEvent event) {
+		Selection newSelection = this.calculateSelection();
+		if (newSelection.equals(this.currentSelection)) {
+			return;
+		}
+		this.currentSelection = newSelection;
+
+		// bug 188344 - won't actively change selection manager selection if 
+		// a "JPA" view is the active (and presumably selecting) view
+		if (this.textEditor.getEditorSite().getPage().getActivePart() instanceof AbstractJpaView) {
+			return;
+		}
+
+		if (this.forwardSelection) {
+			this.selectionManager.select(newSelection);
+		}
+	}
+	
+
+	// ********** listeners **********
+
+	private class EditorInputListener implements IPropertyListener {
+		EditorInputListener() {
+			super();
+		}
 		public void propertyChanged(Object source, int propId) {
-			if ((editor == source) && (propId == IEditorPart.PROP_INPUT)) {
-				editorInputChanged();
+			if ((source == TextEditorSelectionParticipant.this.textEditor)
+						&& (propId == IEditorPart.PROP_INPUT)) {
+				TextEditorSelectionParticipant.this.editorInputChanged();
 			}
 		}
 	}
 	
 	
-	private class EditorSelectionListener
-		implements ISelectionChangedListener 
-	{
+	private class EditorSelectionListener implements ISelectionChangedListener {
+		EditorSelectionListener() {
+			super();
+		}
 		public void selectionChanged(SelectionChangedEvent event) {
-			editorSelectionChanged(event);
+			TextEditorSelectionParticipant.this.editorSelectionChanged(event);
 		}
 	}
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java
index d4654f0..7aaa854 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaDetailsView.java
@@ -104,14 +104,9 @@
 		IJpaDetailsProvider provider = detailsProviders.get(contentId);
 		
 		if (provider == null) {
-			String platformId = contentNode.getJpaProject().getPlatform().getId();
-			IJpaPlatformUi jpaPlatformUI = PlatformRegistry.INSTANCE.getJpaPlatform(platformId);
-			for (IJpaDetailsProvider p : jpaPlatformUI.detailsProviders()) {
-				if (p.fileContentType().equals(contentId)) {
-					provider = p;
-					break;
-				}
-			}
+			String platformId = contentNode.jpaPlatform().getId();
+			IJpaPlatformUi jpaPlatformUI = PlatformRegistry.instance().jpaPlatform(platformId);
+			provider = jpaPlatformUI.detailsProvider(contentId);
 			
 			//TODO this view and the detailsProviders Map is not created on a per project basis.
 			//the detailsProviders and their fileContentTypes could overlap across project, this would cause problems with storing this map.
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaStructureView.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaStructureView.java
index 154ada0..4df3a6f 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaStructureView.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/views/JpaStructureView.java
@@ -201,14 +201,9 @@
 				(IJpaStructureProvider) structureProviders.get(contentId);
 			
 			if (provider == null) {
-				String vendorId = contentNode.getJpaProject().getPlatform().getId();
-				IJpaPlatformUi jpaPlatformUI = PlatformRegistry.INSTANCE.getJpaPlatform(vendorId);
-				for (IJpaStructureProvider p : jpaPlatformUI.structureProviders()) {
-					if (p.fileContentType().equals(contentId)) {
-						provider = p;
-						break;
-					}
-				}
+				String platformId = contentNode.jpaPlatform().getId();
+				IJpaPlatformUi jpaPlatformUI = PlatformRegistry.instance().jpaPlatform(platformId);
+				provider = jpaPlatformUI.structureProvider(contentId);
 				
 				//TODO this view and the detailsProviders Map is not created on a per project basis.
 				//the detailsProviders and their fileContentTypes could overlap across project, this would cause problems with storing this map.				
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseReconnectWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseReconnectWizardPage.java
index 1e7b0d6..f45efff 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseReconnectWizardPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/DatabaseReconnectWizardPage.java
@@ -17,7 +17,6 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.wizard.WizardPage;
 import org.eclipse.jpt.core.internal.IJpaProject;
-import org.eclipse.jpt.db.internal.Connection;
 import org.eclipse.jpt.db.internal.ConnectionListener;
 import org.eclipse.jpt.db.internal.ConnectionProfile;
 import org.eclipse.jpt.db.internal.ConnectionProfileRepository;
@@ -45,7 +44,7 @@
 public class DatabaseReconnectWizardPage extends WizardPage {
 	private IJpaProject jpaProject;
 
-	private Connection connection;
+	private ConnectionProfile profile;
 	private ConnectionListener connectionListener;
 	private DatabaseGroup databaseGroup;
 
@@ -131,8 +130,8 @@
 
 	private void removeConnectionListener() {
 		if ( this.connectionListener != null) {
-			if ( this.connection != null) {
-				this.connection.removeConnectionListener( this.connectionListener);
+			if ( this.profile != null) {
+				this.profile.removeConnectionListener( this.connectionListener);
 			}
 			this.connectionListener = null;
 		}
@@ -230,23 +229,21 @@
 		private String getProjectConnectionProfileName() {
 			return jpaProject.getDataSource().getConnectionProfileName();
 		}
-
+		
 		Schema getDefaultSchema() {
 			ConnectionProfile profile = getProjectConnectionProfile();
 			return profile.getDatabase().schemaNamed( profile.getDefaultSchema());
 		}
 
 		private void openConnectionProfileNamed( String connectionProfileName) {
-			if( DatabaseReconnectWizardPage.this.connection != null) {
-				DatabaseReconnectWizardPage.this.removeConnectionListener();
-			}
-			ConnectionProfile profile = JptDbPlugin.getDefault().getConnectionProfileRepository().profileNamed( connectionProfileName);
-			profile.connect();
-			DatabaseReconnectWizardPage.this.connection = profile.getConnection();
-			if( DatabaseReconnectWizardPage.this.connection != null) {
+			DatabaseReconnectWizardPage.this.removeConnectionListener();
+
+			DatabaseReconnectWizardPage.this.profile = JptDbPlugin.getDefault().getConnectionProfileRepository().profileNamed( connectionProfileName);
+			DatabaseReconnectWizardPage.this.profile.connect();
+			if( DatabaseReconnectWizardPage.this.profile.isConnected()) {
 				this.populateSchemaCombo();
 				DatabaseReconnectWizardPage.this.connectionListener = this.buildConnectionListener();
-				DatabaseReconnectWizardPage.this.connection.addConnectionListener( DatabaseReconnectWizardPage.this.connectionListener);
+				DatabaseReconnectWizardPage.this.profile.addConnectionListener( DatabaseReconnectWizardPage.this.connectionListener);
 			}
 			return;
 		}
@@ -310,6 +307,7 @@
 			ConnectionProfile addedProfile = ConnectionProfileRepository.instance().profileNamed( addedProfileName);
 		
 			if( !addedProfile.isNull()) {
+				addedProfile.connect();
 				this.populateConnectionCombo();
 				this.connectionCombo.select( connectionCombo.indexOf( addedProfile.getName()));
 				this.handleConnectionChange();
@@ -319,40 +317,40 @@
 		private ConnectionListener buildConnectionListener() {
 			return new ConnectionListener() {
 
-				public void modified( Connection connection) {
+				public void modified( ConnectionProfile profile) {
 				// not interested to this event.
 				}
 
-				public boolean okToClose( Connection connection) {
+				public boolean okToClose( ConnectionProfile profile) {
 				// not interested to this event.
 					return true;
 				}
 
-				public void opened( Connection connection) {
-					if( DatabaseReconnectWizardPage.this.connection.equals( connection)) {
+				public void opened( ConnectionProfile profile) {
+					if( DatabaseReconnectWizardPage.this.profile.equals( profile)) {
 						DatabaseGroup.this.populateSchemaCombo();
 					}
 				}
 
-				public void aboutToClose( Connection connection) {
-					if( DatabaseReconnectWizardPage.this.connection.equals( connection)) {
+				public void aboutToClose( ConnectionProfile profile) {
+					if( DatabaseReconnectWizardPage.this.profile.equals( profile)) {
 						DatabaseReconnectWizardPage.this.removeConnectionListener();
 					}
 				}
 
-				public void closed( Connection connection) {
+				public void closed( ConnectionProfile profile) {
 				// not interested to this event.
 				}
 
-				public void databaseChanged(Connection connection, final Database database) {
+				public void databaseChanged(ConnectionProfile profile, final Database database) {
 				// not interested to this event.
 				}
 
-				public void schemaChanged(Connection connection, final Schema schema) {
+				public void schemaChanged(ConnectionProfile profile, final Schema schema) {
 				// not interested to this event.
 				}
 
-				public void tableChanged(Connection connection, final Table table) {
+				public void tableChanged(ConnectionProfile profile, final Table table) {
 				// not interested to this event.
 				}
 			};
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java
index 16e1933..3eb000b 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/wizards/JpaFacetWizardPage.java
@@ -209,7 +209,7 @@
 			platformCombo.setContentProvider(
 					new IStructuredContentProvider() {
 						public Object[] getElements(Object inputElement) {
-							return CollectionTools.array(JpaPlatformRegistry.INSTANCE.allJpaPlatformIds());
+							return CollectionTools.array(JpaPlatformRegistry.instance().allJpaPlatformIds());
 						}
 						
 						public void dispose() {}
@@ -224,7 +224,7 @@
 						}
 						
 						public String getText(Object element) {
-							return JpaPlatformRegistry.INSTANCE.getJpaPlatformLabel((String) element);
+							return JpaPlatformRegistry.instance().jpaPlatformLabel((String) element);
 						}
 						
 						public void addListener(ILabelProviderListener listener) {}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentAttributeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentAttributeDetailsPage.java
index 7940f55..66aaf7f 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentAttributeDetailsPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentAttributeDetailsPage.java
@@ -9,7 +9,10 @@
  ******************************************************************************/
 package org.eclipse.jpt.ui.internal.xml.details;
 
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
 import org.eclipse.emf.common.notify.Adapter;
 import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.notify.impl.AdapterImpl;
@@ -22,8 +25,21 @@
 import org.eclipse.jpt.core.internal.content.orm.XmlPersistentType;
 import org.eclipse.jpt.ui.internal.details.PersistentAttributeDetailsPage;
 import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.BasicMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedIdMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.IdMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToManyMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToOneMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToManyMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToOneMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.TransientMappingUiProvider;
+import org.eclipse.jpt.ui.internal.java.mappings.properties.VersionMappingUiProvider;
 import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
+import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
+import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -42,6 +58,8 @@
 	
 	private IPersistentType persistentType;
 	
+	private List<IAttributeMappingUiProvider> attributeMappingUiProviders;
+
 	public XmlPersistentAttributeDetailsPage(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
 		super(parent, widgetFactory);
 		buildPersistentTypeListener();
@@ -67,8 +85,47 @@
 				});
 		}
 	}
+
+	@Override
+	public ListIterator<IAttributeMappingUiProvider> attributeMappingUiProviders() {
+		if (this.attributeMappingUiProviders == null) {
+			this.attributeMappingUiProviders = new ArrayList<IAttributeMappingUiProvider>();
+			this.addAttributeMappingUiProvidersTo(this.attributeMappingUiProviders);
+		}
+		return new CloneListIterator<IAttributeMappingUiProvider>(this.attributeMappingUiProviders);
+
+	}
+
+	protected void addAttributeMappingUiProvidersTo(List<IAttributeMappingUiProvider> providers) {
+		providers.add(BasicMappingUiProvider.instance());
+		providers.add(EmbeddedMappingUiProvider.instance());
+		providers.add(EmbeddedIdMappingUiProvider.instance());
+		providers.add(IdMappingUiProvider.instance());			
+		providers.add(ManyToManyMappingUiProvider.instance());			
+		providers.add(ManyToOneMappingUiProvider.instance());			
+		providers.add(OneToManyMappingUiProvider.instance());			
+		providers.add(OneToOneMappingUiProvider.instance());
+		providers.add(TransientMappingUiProvider.instance());
+		providers.add(VersionMappingUiProvider.instance());
+	}
 	
 	@Override
+	protected ListIterator<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders() {
+		return EmptyListIterator.instance();
+	}
+	
+	@Override
+	protected IAttributeMappingUiProvider defaultAttributeMappingUiProvider(String key) {
+		throw new UnsupportedOperationException("Xml attributeMappings should not be default");
+	}
+	
+	@Override
+	//bug 192035 - no default mapping option in xml
+	protected IAttributeMappingUiProvider[] attributeMappingUiProvidersFor(IPersistentAttribute persistentAttribute) {
+		return CollectionTools.array(attributeMappingUiProviders(), new IAttributeMappingUiProvider[CollectionTools.size(attributeMappingUiProviders())]);
+	}
+
+	@Override
 	protected void initializeLayout(Composite composite) {
 		composite.setLayout(new GridLayout(2, false));
 		
@@ -163,11 +220,4 @@
 			}
 		}
 	}
-	
-	@Override
-	//TODO Not really how I would want to implement this, but it is low risk fix for bug 192035 for 1.0RC3
-	protected IAttributeMappingUiProvider[] uiProvidersFor(IPersistentAttribute persistentAttribute) {
-		return attributeMappingUiProviders().toArray(new IAttributeMappingUiProvider[attributeMappingUiProviders().size()]);
-	}
-
 }
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentTypeDetailsPage.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentTypeDetailsPage.java
index 3c61547..0c21e16 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentTypeDetailsPage.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/xml/details/XmlPersistentTypeDetailsPage.java
@@ -10,6 +10,8 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jpt.core.internal.AccessType;
 import org.eclipse.jpt.core.internal.IJpaContentNode;
@@ -25,6 +27,7 @@
 import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
 import org.eclipse.jpt.ui.internal.xml.JptUiXmlMessages;
 import org.eclipse.jpt.ui.internal.xml.details.AccessTypeComboViewer.AccessHolder;
+import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -41,16 +44,26 @@
 	
 	private AccessTypeComboViewer accessComboViewer;
 	
+	//Storing these here instead of querying IJpaPlatformUI, because the orm.xml schema
+	//is not extensible.  We only need to support extensibility for java
+	private List<ITypeMappingUiProvider> xmlTypeMappingUiProviders;
+
 	public XmlPersistentTypeDetailsPage(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
 		super(parent, widgetFactory);
 	}
+
+	public ListIterator<ITypeMappingUiProvider> typeMappingUiProviders() {
+		if (this.xmlTypeMappingUiProviders == null) {
+			this.xmlTypeMappingUiProviders = new ArrayList<ITypeMappingUiProvider>();
+			this.addXmlTypeMappingUiProvidersTo(this.xmlTypeMappingUiProviders);
+		}
+		return new CloneListIterator<ITypeMappingUiProvider>(this.xmlTypeMappingUiProviders);
+	}
 	
-	protected Collection<ITypeMappingUiProvider> buildTypeMappingUiProviders() {
-		Collection<ITypeMappingUiProvider> typeMappingUiProviders = new ArrayList<ITypeMappingUiProvider>();
-		typeMappingUiProviders.add(new EntityUiProvider());
-		typeMappingUiProviders.add(new MappedSuperclassUiProvider());			
-		typeMappingUiProviders.add(new EmbeddableUiProvider());			
-		return typeMappingUiProviders;
+	protected void addXmlTypeMappingUiProvidersTo(Collection<ITypeMappingUiProvider> providers) {
+		providers.add(EntityUiProvider.instance());
+		providers.add(MappedSuperclassUiProvider.instance());			
+		providers.add(EmbeddableUiProvider.instance());			
 	}
 	
 	@Override
diff --git a/jpa/plugins/org.eclipse.jpt.utility/.cvsignore b/jpa/plugins/org.eclipse.jpt.utility/.cvsignore
index 42191b4..a128605 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/.cvsignore
+++ b/jpa/plugins/org.eclipse.jpt.utility/.cvsignore
@@ -1,3 +1,4 @@
 bin
 @dot
+temp.folder
 build.xml
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF b/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF
index 20aef05..661346f 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF
+++ b/jpa/plugins/org.eclipse.jpt.utility/META-INF/MANIFEST.MF
@@ -6,5 +6,9 @@
 Bundle-Version: 1.0.0.qualifier
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jpt.utility.internal,
- org.eclipse.jpt.utility.internal.iterators
+ org.eclipse.jpt.utility.internal.iterators,
+ org.eclipse.jpt.utility.internal.model,
+ org.eclipse.jpt.utility.internal.model.event,
+ org.eclipse.jpt.utility.internal.model.listener,
+ org.eclipse.jpt.utility.internal.node
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java
index 2c68536..0dc6f53 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Bag.java
@@ -22,7 +22,7 @@
  */
 
 public interface Bag<E> extends java.util.Collection<E> {
-	
+
 	/**
 	 * Compares the specified object with this bag for equality. Returns
 	 * <code>true</code> if the specified object is also a bag, the two bags
@@ -34,7 +34,7 @@
 	 * bag interface.
 	 */
 	boolean equals(Object o);
-	
+
 	/**
 	 * Returns the hash code value for this bag. The hash code of a bag is
 	 * defined to be the sum of the hash codes of the elements in the bag,
@@ -45,5 +45,28 @@
 	 * contract of the <code>Object.hashCode</code> method.
 	 */
 	int hashCode();
-	
+
+	/**
+	 * Return the number of times the specified object occurs in the bag.
+	 */
+	int count(Object o);
+
+	/**
+	 * Add the specified object the specified number of times to the bag.
+	 */
+	boolean add(E o, int count);
+
+	/**
+	 * Remove the specified number of occurrences of the specified object
+	 * from the bag. Return whether the bag changed.
+	 */
+	boolean remove(Object o, int count);
+
+	/**
+	 * Return an iterator that returns each item in the bag
+	 * once and only once, irrespective of how many times
+	 * the item was added to the bag.
+	 */
+	java.util.Iterator<E> uniqueIterator();
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java
index cc1221a..544f5bb 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BitTools.java
@@ -15,6 +15,38 @@
 public class BitTools {
 
 	/**
+	 * Return whether the specified 'flags' has the specified
+	 * 'flagToCheck' set.
+	 */
+	public static boolean flagIsSet(int flags, int flagToCheck) {
+		return allFlagsAreSet(flags, flagToCheck);
+	}
+
+	/**
+	 * Return whether the specified 'flags' has the specified
+	 * 'flagToCheck' turned off.
+	 */
+	public static boolean flagIsOff(int flags, int flagToCheck) {
+		return allFlagsAreOff(flags, flagToCheck);
+	}
+
+	/**
+	 * Return whether the specified 'flags' has ONLY the specified
+	 * 'flagToCheck' set.
+	 */
+	public static boolean onlyFlagIsSet(int flags, int flagToCheck) {
+		return onlyFlagsAreSet(flags, flagToCheck);
+	}
+
+	/**
+	 * Return whether the specified 'flags' has ONLY the specified
+	 * 'flagToCheck' turned off.
+	 */
+	public static boolean onlyFlagIsOff(int flags, int flagToCheck) {
+		return onlyFlagsAreOff(flags, flagToCheck);
+	}
+
+	/**
 	 * Return whether the specified 'flags' has all the specified
 	 * 'flagsToCheck' set.
 	 */
@@ -23,6 +55,30 @@
 	}
 
 	/**
+	 * Return whether the specified 'flags' has all the specified
+	 * 'flagsToCheck' turned off.
+	 */
+	public static boolean allFlagsAreOff(int flags, int flagsToCheck) {
+		return (flags & flagsToCheck) == 0;
+	}
+
+	/**
+	 * Return whether the specified 'flags' has ONLY the specified
+	 * 'flagsToCheck' set.
+	 */
+	public static boolean onlyFlagsAreSet(int flags, int flagsToCheck) {
+		return allFlagsAreSet(flags, flagsToCheck) && allFlagsAreOff(flags, ~flagsToCheck);
+	}
+
+	/**
+	 * Return whether the specified 'flags' has ONLY the specified
+	 * 'flagsToCheck' turned off.
+	 */
+	public static boolean onlyFlagsAreOff(int flags, int flagsToCheck) {
+		return allFlagsAreOff(flags, flagsToCheck) && allFlagsAreSet(flags, ~flagsToCheck);
+	}
+
+	/**
 	 * Return whether the specified 'flags' has any one of the specified
 	 * 'flagsToCheck' set.
 	 */
@@ -31,6 +87,14 @@
 	}
 
 	/**
+	 * Return whether the specified 'flags' has any one of the specified
+	 * 'flagsToCheck' turned off.
+	 */
+	public static boolean anyFlagsAreOff(int flags, int flagsToCheck) {
+		return (flags & flagsToCheck) != flagsToCheck;
+	}
+
+	/**
 	 * Return whether the specified 'flags' has all the specified
 	 * 'flagsToCheck' set.
 	 */
@@ -44,6 +108,37 @@
 	}
 
 	/**
+	 * Return whether the specified 'flags' has all the specified
+	 * 'flagsToCheck' turned off.
+	 */
+	public static boolean allFlagsAreOff(int flags, int[] flagsToCheck) {
+		for (int i = flagsToCheck.length; i-- > 0; ) {
+			if ( ! allFlagsAreOff(flags, flagsToCheck[i])) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Return whether the specified 'flags' has ONLY the specified
+	 * 'flagsToCheck' set.
+	 */
+	public static boolean onlyFlagsAreSet(int flags, int[] flagsToCheck) {
+		int combinedFlags = orFlags(flagsToCheck);
+		return allFlagsAreSet(flags, combinedFlags) && allFlagsAreOff(flags, ~combinedFlags);
+	}
+
+	/**
+	 * Return whether the specified 'flags' has ONLY the specified
+	 * 'flagsToCheck' turned off.
+	 */
+	public static boolean onlyFlagsAreOff(int flags, int[] flagsToCheck) {
+		int combinedFlags = orFlags(flagsToCheck);
+		return allFlagsAreOff(flags, combinedFlags) && allFlagsAreSet(flags, ~combinedFlags);
+	}
+
+	/**
 	 * Return whether the specified 'flags' has any one of the specified
 	 * 'flagsToCheck' set.
 	 */
@@ -56,6 +151,55 @@
 		return false;
 	}
 
+	/**
+	 * Return whether the specified 'flags' has any one of the specified
+	 * 'flagsToCheck' turned off.
+	 */
+	public static boolean anyFlagsAreOff(int flags, int[] flagsToCheck) {
+		for (int i = flagsToCheck.length; i-- > 0; ) {
+			if (anyFlagsAreOff(flags, flagsToCheck[i])) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * OR all the specified 'flags' together and return the result.
+	 */
+	public static int orFlags(int[] flags) {
+		int last = flags.length - 1;
+		int result = flags[last];
+		for (int i = last; i-- > 0; ) {
+			result |= flags[i];
+		}
+		return result;
+	}
+
+	/**
+	 * AND all the specified 'flags' together and return the result.
+	 */
+	public static int andFlags(int[] flags) {
+		int last = flags.length - 1;
+		int result = flags[last];
+		for (int i = last; i-- > 0; ) {
+			result &= flags[i];
+		}
+		return result;
+	}
+
+	/**
+	 * XOR all the specified 'flags' together and return the result.
+	 */
+	public static int xorFlags(int[] flags) {
+		int last = flags.length - 1;
+		int result = flags[last];
+		for (int i = last; i-- > 0; ) {
+			result ^= flags[i];
+		}
+		return result;
+	}
+
 
 	// ********** constructor **********
 
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
index 9f8e202..ea45fb8 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/ClassTools.java
@@ -731,13 +731,13 @@
 	
 	/**
 	 * Convenience method.
-	 * Return the specified class,.
+	 * Return the specified class (without the checked exception).
 	 */
-	public static Class<?> classForName(String javaClassName) {
+	public static Class<?> classForName(String className) {
 		try {
-			return Class.forName(javaClassName);
+			return Class.forName(className);
 		} catch (ClassNotFoundException ex) {
-			throw new RuntimeException(javaClassName, ex);
+			throw new RuntimeException(className, ex);
 		}
 	}
 	
@@ -757,8 +757,8 @@
 	 * using the class's default (zero-argument) constructor.
 	 * Class#newInstance()
 	 */
-	public static Object newInstance(String javaClassName) throws ClassNotFoundException {
-		return newInstance(javaClassName, ClassTools.class.getClassLoader());
+	public static Object newInstance(String className) throws ClassNotFoundException {
+		return newInstance(className, null);
 	}
 	
 	/**
@@ -767,8 +767,8 @@
 	 * using the class's default (zero-argument) constructor.
 	 * Class#newInstance()
 	 */
-	public static Object newInstance(String javaClassName, ClassLoader classLoader) throws ClassNotFoundException {
-		return newInstance(classLoader.loadClass(javaClassName));
+	public static Object newInstance(String className, ClassLoader classLoader) throws ClassNotFoundException {
+		return newInstance(Class.forName(className, true, classLoader));
 	}
 	
 	/**
@@ -789,8 +789,8 @@
 	 * given the constructor parameter types and parameters.
 	 * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
 	 */
-	public static Object newInstance(String javaClassName, Class<?>[] parameterTypes, Object[] parameters) throws ClassNotFoundException {
-		return newInstance(javaClassName, parameterTypes, parameters, ClassTools.class.getClassLoader());
+	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters) throws ClassNotFoundException {
+		return newInstance(className, parameterTypes, parameters, null);
 	}
 	
 	/**
@@ -798,8 +798,8 @@
 	 * given the constructor parameter types and parameters.
 	 * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
 	 */
-	public static Object newInstance(String javaClassName, Class<?>[] parameterTypes, Object[] parameters, ClassLoader classLoader) throws ClassNotFoundException {
-		return newInstance(classLoader.loadClass(javaClassName), parameterTypes, parameters);
+	public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters, ClassLoader classLoader) throws ClassNotFoundException {
+		return newInstance(Class.forName(className, true, classLoader), parameterTypes, parameters);
 	}
 	
 	/**
@@ -817,8 +817,8 @@
 	 * given the constructor parameter type and parameter.
 	 * Class#newInstance(Class<?> parameterType, Object parameter)
 	 */
-	public static Object newInstance(String javaClassName, Class<?> parameterType, Object parameter) throws ClassNotFoundException {
-		return newInstance(javaClassName, parameterType, parameter, ClassTools.class.getClassLoader());
+	public static Object newInstance(String className, Class<?> parameterType, Object parameter) throws ClassNotFoundException {
+		return newInstance(className, parameterType, parameter, null);
 	}
 	
 	/**
@@ -826,8 +826,8 @@
 	 * given the constructor parameter type and parameter.
 	 * Class#newInstance(Class<?> parameterType, Object parameter)
 	 */
-	public static Object newInstance(String javaClassName, Class<?> parameterType, Object parameter, ClassLoader classLoader) throws ClassNotFoundException {
-		return newInstance(classLoader.loadClass(javaClassName), parameterType, parameter);
+	public static Object newInstance(String className, Class<?> parameterType, Object parameter, ClassLoader classLoader) throws ClassNotFoundException {
+		return newInstance(Class.forName(className, false, classLoader), parameterType, parameter);
 	}
 	
 	/**
@@ -1360,13 +1360,14 @@
 	 * Return the class for specified "type declaration".
 	 */
 	public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth) throws ClassNotFoundException {
-		return classForTypeDeclaration(elementTypeName, arrayDepth, ClassTools.class.getClassLoader());
+		return classForTypeDeclaration(elementTypeName, arrayDepth, null);
 	}
 	
 	/**
 	 * Return the class for specified "type declaration",
 	 * using the specified class loader.
 	 */
+	// see the "Evaluation" of jdk bug 6446627 for a discussion of loading classes
 	public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) throws ClassNotFoundException {
 		// primitives cannot be loaded via Class#forName(),
 		// so check for a primitive class name first
@@ -1383,7 +1384,7 @@
 
 		// non-array
 		if (arrayDepth == 0) {
-			return (pcc == null) ? classLoader.loadClass(elementTypeName) : pcc.javaClass;
+			return (pcc == null) ? Class.forName(elementTypeName, false, classLoader) : pcc.javaClass;
 		}
 
 		// array
@@ -1398,7 +1399,7 @@
 		} else {
 			sb.append(pcc.code);
 		}
-		return classLoader.loadClass(sb.toString());
+		return Class.forName(sb.toString(), false, classLoader);
 	}
 	
 	/**
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java
index 0eac533..99b2d1b 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Classpath.java
@@ -581,7 +581,7 @@
 	 * duplicate entries eliminated.
 	 */
 	public Classpath compressed() {
-		return new Classpath((Entry[]) CollectionTools.removeDuplicateElements(this.entries));
+		return new Classpath(CollectionTools.removeDuplicateElements(this.entries));
 	}
 
 	/**
@@ -705,7 +705,7 @@
 				zipFile = new ZipFile(this.canonicalFile);
 				zipEntry = zipFile.getEntry(zipEntryName);
 			} catch (IOException ex) {
-				zipEntry = null;	// something is wrong, clear out the entry
+				// something is wrong, leave the entry null
 			} finally {
 				try {
 					if (zipFile != null) {
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java
index e4df43b..8259ad8 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CollectionTools.java
@@ -35,9 +35,9 @@
 	 * specified array followed by the specified object to be added.
 	 * java.util.Arrays#add(Object[] array, Object o)
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] add(E[] array, E value) {
 		int len = array.length;
+		@SuppressWarnings("unchecked")
 		E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), len + 1);
 		System.arraycopy(array, 0, result, 0, len);
 		result[len] = value;
@@ -49,9 +49,9 @@
 	 * specified array with the specified object added at the specified index.
 	 * java.util.Arrays#add(Object[] array, int index, Object o)
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] add(E[] array, int index, E value) {
 		int len = array.length;
+		@SuppressWarnings("unchecked")
 		E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), len + 1);
 		if (index > 0) {
 			System.arraycopy(array, 0, result, 0, index);
@@ -118,6 +118,16 @@
 	}
 
 	/**
+	 * Add all the elements returned by the specified iterable
+	 * to the specified collection.
+	 * Return whether the collection changed as a result.
+	 * java.util.Collection#addAll(java.lang.Iterable iterable)
+	 */
+	public static <E> boolean addAll(Collection<? super E> collection, Iterable<E> iterable) {
+		return addAll(collection, iterable.iterator());
+	}
+
+	/**
 	 * Add all the elements returned by the specified iterator
 	 * to the specified collection.
 	 * Return whether the collection changed as a result.
@@ -151,9 +161,9 @@
 	 * in the specified collection.
 	 * java.util.Arrays#addAll(Object[] array, java.util.Collection c)
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] addAll(E[] array, Collection<? extends E> collection) {
 		int len = array.length;
+		@SuppressWarnings("unchecked")
 		E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), array.length + collection.size());
 		System.arraycopy(array, 0, result, 0, len);
 		int i = len;
@@ -166,6 +176,16 @@
 	/**
 	 * Return a new array that contains the elements in the
 	 * specified array followed by the elements
+	 * in the specified iterable.
+	 * java.util.Arrays#addAll(Object[] array, java.lang.Iterable iterable)
+	 */
+	public static <E> E[] addAll(E[] array, Iterable<? extends E> iterable) {
+		return addAll(array, iterable.iterator());
+	}
+
+	/**
+	 * Return a new array that contains the elements in the
+	 * specified array followed by the elements
 	 * in the specified iterator.
 	 * java.util.Arrays#addAll(Object[] array, java.util.Iterator iterator)
 	 */
@@ -179,10 +199,10 @@
 	 * in the specified array 2.
 	 * java.util.Arrays#addAll(Object[] array1, Object[] array2)
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] addAll(E[] array1, E[] array2) {
 		int len1 = array1.length;
 		int len2 = array2.length;
+		@SuppressWarnings("unchecked")
 		E[] result = (E[]) Array.newInstance(array1.getClass().getComponentType(), len1 + len2);
 		System.arraycopy(array1, 0, result, 0, len1);
 		System.arraycopy(array2, 0, result, len1, len2);
@@ -195,10 +215,10 @@
 	 * specified array added at the specified index.
 	 * java.util.Arrays#add(Object[] array1, int index, Object[] array2)
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] addAll(E[] array1, int index, E[] array2) {
 		int len1 = array1.length;
 		int len2 = array2.length;
+		@SuppressWarnings("unchecked")
 		E[] result = (E[]) Array.newInstance(array1.getClass().getComponentType(), len1 + len2);
 		System.arraycopy(array1, 0, result, 0, index);
 		System.arraycopy(array2, 0, result, index, len2);
@@ -269,6 +289,28 @@
 	}
 
 	/**
+	 * Return an array corresponding to the specified iterable.
+	 * @see java.util.Collection#toArray()
+	 * java.lang.Iterable#toArray()
+	 */
+	public static Object[] array(Iterable<?> iterable) {
+		return array(iterable.iterator());
+	}
+
+	/**
+	 * Return an array corresponding to the specified iterable;
+	 * the runtime type of the returned array is that of the specified array.
+	 * If the collection fits in the specified array, it is returned therein.
+	 * Otherwise, a new array is allocated with the runtime type of the
+	 * specified array and the size of this collection.
+	 * @see java.util.Collection#toArray(java.lang.Object[])
+	 * java.lang.Iterable#toArray(Object[])
+	 */
+	public static <E> E[] array(Iterable<? extends E> iterable, E[] array) {
+		return array(iterable.iterator(), array);
+	}
+
+	/**
 	 * Return an array corresponding to the specified iterator.
 	 * @see java.util.Collection#toArray()
 	 * java.util.Iterator#toArray()
@@ -303,6 +345,14 @@
 	}
 
 	/**
+	 * Return a bag corresponding to the specified iterable.
+	 * HashBag(java.lang.Iterable iterable)
+	 */
+	public static <E> Bag<E> bag(Iterable<? extends E> iterable) {
+		return bag(iterable.iterator());
+	}
+
+	/**
 	 * Return a bag corresponding to the specified iterator.
 	 * HashBag(java.util.Iterator iterator)
 	 */
@@ -334,6 +384,13 @@
 	}
 
 	/**
+	 * Return a collection corresponding to the specified iterable.
+	 */
+	public static <E> Collection<E> collection(Iterable<? extends E> iterable) {
+		return collection(iterable.iterator());
+	}
+
+	/**
 	 * Return a collection corresponding to the specified iterator.
 	 */
 	public static <E> Collection<E> collection(Iterator<? extends E> iterator) {
@@ -370,6 +427,15 @@
 	}
 
 	/**
+	 * Return whether the specified iterable contains the
+	 * specified element.
+	 * java.lang.Iterable#contains(Object o)
+	 */
+	public static boolean contains(Iterable<?> iterable, Object value) {
+		return contains(iterable.iterator(), value);
+	}
+
+	/**
 	 * Return whether the specified iterator contains the
 	 * specified element.
 	 * java.util.Iterator#contains(Object o)
@@ -443,6 +509,15 @@
 
 	/**
 	 * Return whether the specified collection contains all of the
+	 * elements in the specified iterable.
+	 * java.util.Collection#containsAll(java.lang.Iterable iterable)
+	 */
+	public static boolean containsAll(Collection<?> collection, Iterable<?> iterable) {
+		return containsAll(collection, iterable.iterator());
+	}
+
+	/**
+	 * Return whether the specified collection contains all of the
 	 * elements in the specified iterator.
 	 * java.util.Collection#containsAll(java.util.Iterator iterator)
 	 */
@@ -470,6 +545,42 @@
 	}
 
 	/**
+	 * Return whether the specified iterable contains all of the
+	 * elements in the specified collection.
+	 * java.lang.Iterable#containsAll(java.util.Collection collection)
+	 */
+	public static boolean containsAll(Iterable<?> iterable, Collection<?> collection) {
+		return containsAll(iterable.iterator(), collection);
+	}
+
+	/**
+	 * Return whether the specified iterable 1 contains all of the
+	 * elements in the specified iterable 2.
+	 * java.lang.Iterable#containsAll(java.lang.Iterable iterable)
+	 */
+	public static boolean containsAll(Iterable<?> iterable1, Iterable<?> iterable2) {
+		return containsAll(iterable1.iterator(), iterable2.iterator());
+	}
+
+	/**
+	 * Return whether the specified iterable contains all of the
+	 * elements in the specified iterator.
+	 * java.lang.Iterable#containsAll(java.util.Iterator iterator)
+	 */
+	public static boolean containsAll(Iterable<?> iterable, Iterator<?> iterator) {
+		return containsAll(iterable.iterator(), iterator);
+	}
+
+	/**
+	 * Return whether the specified iterable contains all of the
+	 * elements in the specified array.
+	 * java.lang.Iterable#containsAll(Object[] array)
+	 */
+	public static boolean containsAll(Iterable<?> iterable, Object[] array) {
+		return containsAll(iterable.iterator(), array);
+	}
+
+	/**
 	 * Return whether the specified iterator contains all of the
 	 * elements in the specified collection.
 	 * java.util.Iterator#containsAll(java.util.Collection collection)
@@ -479,6 +590,15 @@
 	}
 
 	/**
+	 * Return whether the specified iterator contains all of the
+	 * elements in the specified iterable.
+	 * java.util.Iterator#containsAll(java.lang.Iterable iterable)
+	 */
+	public static boolean containsAll(Iterator<?> iterator, Iterable<?> iterable) {
+		return containsAll(collection(iterator), iterable);
+	}
+
+	/**
 	 * Return whether the specified iterator 1 contains all of the
 	 * elements in the specified iterator 2.
 	 * java.util.Iterator#containsAll(java.util.Iterator iterator)
@@ -507,6 +627,15 @@
 
 	/**
 	 * Return whether the specified array contains all of the
+	 * elements in the specified iterable.
+	 * java.util.Arrays#containsAll(Object[] array, java.lang.Iterable iterable)
+	 */
+	public static boolean containsAll(Object[] array, Iterable<?> iterable) {
+		return containsAll(array, iterable.iterator());
+	}
+
+	/**
+	 * Return whether the specified array contains all of the
 	 * elements in the specified iterator.
 	 * java.util.Arrays#containsAll(Object[] array, java.util.Iterator iterator)
 	 */
@@ -999,6 +1128,14 @@
 	}
 
 	/**
+	 * Return an iterable on the elements in the specified array.
+	 * java.util.Arrays#iterable(Object[] array)
+	 */
+	public static <E> Iterable<E> iterable(E... array) {
+		return Arrays.asList(array);
+	}
+
+	/**
 	 * Return an iterator on the elements in the specified array.
 	 * java.util.Arrays#iterator(Object[] array)
 	 */
@@ -1071,6 +1208,14 @@
 	}
 
 	/**
+	 * Return a list corresponding to the specified iterable.
+	 * java.lang.Iterable#toList()
+	 */
+	public static <E> List<E> list(Iterable<? extends E> iterable) {
+		return list(iterable.iterator());
+	}
+
+	/**
 	 * Return a list corresponding to the specified iterator.
 	 * java.util.Iterator#toList()
 	 */
@@ -1193,6 +1338,148 @@
 	}
 
 	/**
+	 * Move an element from the specified source index to the specified target
+	 * index. Return the altered array.
+	 * java.util.Arrays#move(Object[] array, int targetIndex, int sourceIndex)
+	 */
+	public static <E> E[] move(E[] array, int targetIndex, int sourceIndex) {
+		if (targetIndex == sourceIndex) {
+			return array;
+		}
+		E temp = array[sourceIndex];
+		if (targetIndex < sourceIndex) {
+			System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex);
+		} else {
+			System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex);
+		}
+		array[targetIndex] = temp;
+		return array;
+	}
+
+	/**
+	 * Move elements from the specified source index to the specified target
+	 * index. Return the altered array.
+	 * java.util.Arrays#move(Object[] array, int targetIndex, int sourceIndex, int length)
+	 */
+	public static <E> E[] move(E[] array, int targetIndex, int sourceIndex, int length) {
+		if (targetIndex == sourceIndex) {
+			return array;
+		}
+		@SuppressWarnings("unchecked")
+		E[] temp = (E[]) Array.newInstance(array.getClass().getComponentType(), length);
+		System.arraycopy(array, sourceIndex, temp, 0, length);
+		if (targetIndex < sourceIndex) {
+			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
+		} else {
+			System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex);
+		}
+		System.arraycopy(temp, 0, array, targetIndex, length);
+		return array;
+	}
+
+	/**
+	 * Move an element from the specified source index to the specified target
+	 * index. Return the altered array.
+	 * java.util.Arrays#move(int[] array, int targetIndex, int sourceIndex)
+	 */
+	public static int[] move(int[] array, int targetIndex, int sourceIndex) {
+		if (targetIndex == sourceIndex) {
+			return array;
+		}
+		int temp = array[sourceIndex];
+		if (targetIndex < sourceIndex) {
+			System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex);
+		} else {
+			System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex);
+		}
+		array[targetIndex] = temp;
+		return array;
+	}
+
+	/**
+	 * Move elements from the specified source index to the specified target
+	 * index. Return the altered array.
+	 * java.util.Arrays#move(int[] array, int targetIndex, int sourceIndex, int length)
+	 */
+	public static int[] move(int[] array, int targetIndex, int sourceIndex, int length) {
+		if (targetIndex == sourceIndex) {
+			return array;
+		}
+		int[] temp = new int[length];
+		System.arraycopy(array, sourceIndex, temp, 0, length);
+		if (targetIndex < sourceIndex) {
+			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
+		} else {
+			System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex);
+		}
+		System.arraycopy(temp, 0, array, targetIndex, length);
+		return array;
+	}
+
+	/**
+	 * Move an element from the specified source index to the specified target
+	 * index. Return the altered array.
+	 * java.util.Arrays#move(char[] array, int targetIndex, int sourceIndex)
+	 */
+	public static char[] move(char[] array, int targetIndex, int sourceIndex) {
+		if (targetIndex == sourceIndex) {
+			return array;
+		}
+		char temp = array[sourceIndex];
+		if (targetIndex < sourceIndex) {
+			System.arraycopy(array, targetIndex, array, targetIndex + 1, sourceIndex - targetIndex);
+		} else {
+			System.arraycopy(array, sourceIndex + 1, array, sourceIndex, targetIndex - sourceIndex);
+		}
+		array[targetIndex] = temp;
+		return array;
+	}
+
+	/**
+	 * Move elements from the specified source index to the specified target
+	 * index. Return the altered array.
+	 * java.util.Arrays#move(char[] array, int targetIndex, int sourceIndex, int length)
+	 */
+	public static char[] move(char[] array, int targetIndex, int sourceIndex, int length) {
+		if (targetIndex == sourceIndex) {
+			return array;
+		}
+		char[] temp = new char[length];
+		System.arraycopy(array, sourceIndex, temp, 0, length);
+		if (targetIndex < sourceIndex) {
+			System.arraycopy(array, targetIndex, array, targetIndex + length, sourceIndex - targetIndex);
+		} else {
+			System.arraycopy(array, sourceIndex + length, array, sourceIndex, targetIndex - sourceIndex);
+		}
+		System.arraycopy(temp, 0, array, targetIndex, length);
+		return array;
+	}
+
+	/**
+	 * Move an element from the specified source index to the specified target
+	 * index. Return the altered list.
+	 * java.util.List#move(int targetIndex, int sourceIndex)
+	 */
+	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex) {
+		if (targetIndex != sourceIndex) {
+			list.add(targetIndex, list.remove(sourceIndex));
+		}
+		return list;
+	}
+
+	/**
+	 * Move elements from the specified source index to the specified target
+	 * index. Return the altered list.
+	 * java.util.List#move(int targetIndex, int sourceIndex, int length)
+	 */
+	public static <E> List<E> move(List<E> list, int targetIndex, int sourceIndex, int length) {
+		if (targetIndex != sourceIndex) {
+			list.addAll(targetIndex, removeElementsAtIndex(list, sourceIndex, length));
+		}
+		return list;
+	}
+
+	/**
 	 * Replace all occurrences of the specified old value with
 	 * the specified new value.
 	 * java.util.Arrays#replaceAll(Object[] array, Object oldValue, Object newValue)
@@ -1270,6 +1557,16 @@
 	}
 
 	/**
+	 * Remove all the elements returned by the specified iterable
+	 * from the specified collection.
+	 * Return whether the collection changed as a result.
+	 * java.util.Collection#removeAll(java.lang.Iterable iterable)
+	 */
+	public static boolean removeAll(Collection<?> collection, Iterable<?> iterable) {
+		return removeAll(collection, iterable.iterator());
+	}
+
+	/**
 	 * Remove all the elements returned by the specified iterator
 	 * from the specified collection.
 	 * Return whether the collection changed as a result.
@@ -1454,13 +1751,8 @@
 	 * specified array with the specified element removed.
 	 * java.util.Arrays#removeElementAtIndex(Object[] array, int index)
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] removeElementAtIndex(E[] array, int index) {
-		int len = array.length;
-		E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), len - 1);
-		System.arraycopy(array, 0, result, 0, index);
-		System.arraycopy(array, index + 1, result, index, len - index - 1);
-		return result;
+		return removeElementsAtIndex(array, index, 1);
 	}
 
 	/**
@@ -1469,11 +1761,7 @@
 	 * java.util.Arrays#removeElementAtIndex(char[] array, int index)
 	 */
 	public static char[] removeElementAtIndex(char[] array, int index) {
-		int len = array.length;
-		char[] result = new char[len - 1];
-		System.arraycopy(array, 0, result, 0, index);
-		System.arraycopy(array, index + 1, result, index, len - index - 1);
-		return result;
+		return removeElementsAtIndex(array, index, 1);
 	}
 
 	/**
@@ -1482,10 +1770,59 @@
 	 * java.util.Arrays#removeElementAtIndex(int[] array, int index)
 	 */
 	public static int[] removeElementAtIndex(int[] array, int index) {
+		return removeElementsAtIndex(array, index, 1);
+	}
+
+	/**
+	 * Remove the elements at the specified index.
+	 * Return the removed elements.
+	 * java.util.List#remove(int index, int length)
+	 */
+	public static <E> List<E> removeElementsAtIndex(List<E> list, int index, int length) {
+		ArrayList<E> result = new ArrayList<E>(list.subList(index, index + length));
+		for (int i = length; i-- > 0; ) {
+			list.remove(index);
+		}
+		return result;
+	}
+
+	/**
+	 * Return a new array that contains the elements in the
+	 * specified array with the specified elements removed.
+	 * java.util.Arrays#removeElementsAtIndex(Object[] array, int index, int length)
+	 */
+	public static <E> E[] removeElementsAtIndex(E[] array, int index, int length) {
 		int len = array.length;
-		int[] result = new int[len - 1];
+		@SuppressWarnings("unchecked")
+		E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), len - length);
 		System.arraycopy(array, 0, result, 0, index);
-		System.arraycopy(array, index + 1, result, index, len - index - 1);
+		System.arraycopy(array, index + length, result, index, len - index - length);
+		return result;
+	}
+
+	/**
+	 * Return a new array that contains the elements in the
+	 * specified array with the specified elements removed.
+	 * java.util.Arrays#removeElementAtIndex(char[] array, int index, int length)
+	 */
+	public static char[] removeElementsAtIndex(char[] array, int index, int length) {
+		int len = array.length;
+		char[] result = new char[len - length];
+		System.arraycopy(array, 0, result, 0, index);
+		System.arraycopy(array, index + length, result, index, len - index - length);
+		return result;
+	}
+
+	/**
+	 * Return a new array that contains the elements in the
+	 * specified array with the specified elements removed.
+	 * java.util.Arrays#removeElementAtIndex(int[] array, int index, int length)
+	 */
+	public static int[] removeElementsAtIndex(int[] array, int index, int length) {
+		int len = array.length;
+		int[] result = new int[len - length];
+		System.arraycopy(array, 0, result, 0, index);
+		System.arraycopy(array, index + length, result, index, len - index - length);
 		return result;
 	}
 
@@ -1493,10 +1830,11 @@
 	 * Remove any duplicate elements from the specified array,
 	 * while maintaining the order.
 	 */
-	@SuppressWarnings("unchecked")
 	public static <E> E[] removeDuplicateElements(E... array) {
 		List<E> list = removeDuplicateElements(Arrays.asList(array));
-		return list.toArray((E[]) Array.newInstance(array.getClass().getComponentType(), list.size()));
+		@SuppressWarnings("unchecked")
+		E[] resultArray = (E[]) Array.newInstance(array.getClass().getComponentType(), list.size());
+		return list.toArray(resultArray);
 	}
 
 	/**
@@ -1515,6 +1853,16 @@
 	}
 
 	/**
+	 * Retain only the elements in the specified iterable
+	 * in the specified collection.
+	 * Return whether the collection changed as a result.
+	 * java.util.Collection#retainAll(java.lang.Iterable iterable)
+	 */
+	public static boolean retainAll(Collection<?> collection, Iterable<?> iterable) {
+		return retainAll(collection, iterable.iterator());
+	}
+
+	/**
 	 * Retain only the elements in the specified iterator
 	 * in the specified collection.
 	 * Return whether the collection changed as a result.
@@ -1635,6 +1983,14 @@
 
 	/**
 	 * Return a list with entries in reverse order from those
+	 * returned by the specified iterable.
+	 */
+	public static <E> List<E> reverseList(Iterable<? extends E> iterable) {
+		return reverse(list(iterable));
+	}
+
+	/**
+	 * Return a list with entries in reverse order from those
 	 * returned by the specified iterator.
 	 */
 	public static <E> List<E> reverseList(Iterator<? extends E> iterator) {
@@ -1765,6 +2121,14 @@
 	}
 
 	/**
+	 * Return a set corresponding to the specified iterable.
+	 * java.util.HashSet(java.lang.Iterable iterable)
+	 */
+	public static <E> Set<E> set(Iterable<? extends E> iterable) {
+		return set(iterable.iterator());
+	}
+
+	/**
 	 * Return a set corresponding to the specified iterator.
 	 * java.util.HashSet(java.util.Iterator iterator)
 	 */
@@ -1860,6 +2224,14 @@
 	}
 
 	/**
+	 * Return the number of elements returned by the specified iterable.
+	 * java.lang.Iterable#size()
+	 */
+	public static int size(Iterable<?> iterable) {
+		return size(iterable.iterator());
+	}
+
+	/**
 	 * Return the number of elements returned by the specified iterator.
 	 * java.util.Iterator#size()
 	 */
@@ -1873,6 +2245,23 @@
 	}
 
 	/**
+	 * Return a sorted set corresponding to the specified iterable.
+	 * java.util.TreeSet(java.lang.Iterable iterable)
+	 */
+	public static <E extends Comparable<? super E>> SortedSet<E> sortedSet(Iterable<? extends E> iterable) {
+		return sortedSet(iterable, null);
+	}
+
+	/**
+	 * Return a sorted set corresponding to the specified iterable
+	 * and comparator.
+	 * java.util.TreeSet(java.lang.Iterable iterable, java.util.Comparator c)
+	 */
+	public static <E> SortedSet<E> sortedSet(Iterable<? extends E> iterable, Comparator<? super E> comparator) {
+		return sortedSet(iterable.iterator(), comparator);
+	}
+
+	/**
 	 * Return a sorted set corresponding to the specified iterator.
 	 * java.util.TreeSet(java.util.Iterator iterator)
 	 */
@@ -1911,6 +2300,40 @@
 	}
 
 	/**
+	 * Return a sub-array of the specified array, starting at the specified
+	 * position with the specified length.
+	 * java.util.Arrays#subArray(E[] array, int start, int length)
+	 */
+	public static <E> E[] subArray(E[] array, int start, int length) {
+		@SuppressWarnings("unchecked")
+		E[] result = (E[]) Array.newInstance(array.getClass().getComponentType(), length);
+		System.arraycopy(array, start, result, 0, length);
+		return result;
+	}
+
+	/**
+	 * Return a sub-array of the specified array, starting at the specified
+	 * position with the specified length.
+	 * java.util.Arrays#subArray(int[] array, int start, int length)
+	 */
+	public static int[] subArray(int[] array, int start, int length) {
+		int[] result = new int[length];
+		System.arraycopy(array, start, result, 0, length);
+		return result;
+	}
+
+	/**
+	 * Return a sub-array of the specified array, starting at the specified
+	 * position with the specified length.
+	 * java.util.Arrays#subArray(char[] array, int start, int length)
+	 */
+	public static char[] subArray(char[] array, int start, int length) {
+		char[] result = new char[length];
+		System.arraycopy(array, start, result, 0, length);
+		return result;
+	}
+
+	/**
 	 * Return the array after the specified elements have been "swapped".
 	 * java.util.Arrays#swap(Object[] array, int i, int j)
 	 */
@@ -1944,6 +2367,15 @@
 	}
 
 	/**
+	 * Return a vector corresponding to the specified iterable.
+	 * This is useful for legacy code that requires a java.util.Vector.
+	 * java.util.Vector(java.lang.Iterable iterable)
+	 */
+	public static <E> Vector<E> vector(Iterable<? extends E> iterable) {
+		return vector(iterable.iterator());
+	}
+
+	/**
 	 * Return a vector corresponding to the specified iterator.
 	 * This is useful for legacy code that requires a java.util.Vector.
 	 * java.util.Vector(java.util.Iterator iterator)
@@ -2054,6 +2486,20 @@
 	}
 
 	/**
+	 * Return the iterable after it has been "sorted".
+	 */
+	public static <E extends Comparable<? super E>> Iterable<E> sort(Iterable<E> iterable) {
+		return sort(iterable, null);
+	}
+
+	/**
+	 * Return the iterable after it has been "sorted".
+	 */
+	public static <E> Iterable<E> sort(Iterable<E> iterable, Comparator<? super E> comparator) {
+		return sort(list(iterable), comparator);
+	}
+
+	/**
 	 * Return the iterator after it has been "sorted".
 	 */
 	public static <E extends Comparable<? super E>> Iterator<E> sort(Iterator<E> iterator) {
@@ -2061,7 +2507,7 @@
 	}
 
 	/**
-	 * Return the list after it has been "sorted".
+	 * Return the iterator after it has been "sorted".
 	 */
 	public static <E> Iterator<E> sort(Iterator<E> iterator, Comparator<? super E> comparator) {
 		return sort(list(iterator), comparator).iterator();
@@ -2344,7 +2790,7 @@
 	 * Return the array after it has been "sorted".
 	 * @see java.util.Arrays#sort(Object[], java.util.Comparator)
 	 */
-    public static <E> E[] sort(E[] array, Comparator<? super E> comparator) {
+	public static <E> E[] sort(E[] array, Comparator<? super E> comparator) {
 		Arrays.sort(array, comparator);
 		return array;
 	}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Command.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Command.java
new file mode 100644
index 0000000..4e10619
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Command.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+/**
+ * Simple interface for implementing the GOF Command design pattern.
+ */
+public interface Command {
+
+	/**
+	 * Execute the command. The semantics of the command
+	 * is determined by the contract between the client and server.
+	 */
+	void execute();
+
+	final class Null implements Command {
+		public static final Command INSTANCE = new Null();
+		public static Command instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Null() {
+			super();
+		}
+		public void execute() {
+			// do nothing
+		}
+		@Override
+		public String toString() {
+			return "Command.Null";
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandExecutor.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandExecutor.java
new file mode 100644
index 0000000..3ea7181
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandExecutor.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+/**
+ * This interface allows clients to control how a command is executed
+ * (e.g. dispatching the command to the UI thread).
+ */
+public interface CommandExecutor {
+
+	/**
+	 * Execute the specified command.
+	 */
+	void execute(Command command);
+
+
+	/**
+	 * Straightforward implementation of the command executor interface
+	 * that simply executes the command without any sort of enhancement.
+	 */
+	final class Default implements CommandExecutor {
+		public static final CommandExecutor INSTANCE = new Default();
+		public static CommandExecutor instance() {
+			return INSTANCE;
+		}
+		// ensure single instance
+		private Default() {
+			super();
+		}
+		public void execute(Command command) {
+			command.execute();
+		}
+		@Override
+		public String toString() {
+			return "CommandExecutor.Default";
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandExecutorProvider.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandExecutorProvider.java
new file mode 100644
index 0000000..ee20983
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/CommandExecutorProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+/**
+ * Yet another level of indirection to allow clients to control
+ * how a command is executed by the server
+ * (e.g. dispatching the command to the UI thread).
+ */
+public interface CommandExecutorProvider {
+
+	/**
+	 * Return the appropriate command executor.
+	 */
+	CommandExecutor commandExecutor();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java
index 5017cf9..ac4e578 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/HashBag.java
@@ -61,7 +61,7 @@
 
 	/** The hash table. */
 	transient Entry<E>[] table;
-	
+
 	/** The total number of entries in the bag. */
 	transient int count = 0;
 
@@ -75,14 +75,14 @@
 	 * @serial
 	 */
 	private int threshold;
-	
+
 	/**
 	 * The load factor for the hash table.
 	 *
 	 * @serial
 	 */
 	private float loadFactor;
-	
+
 	/**
 	 * The number of times this bag has been structurally modified.
 	 * Structural modifications are those that change the number of entries in
@@ -100,7 +100,7 @@
 	public HashBag() {
 		this(11, 0.75f);
 	}
-	
+
 	/**
 	 * Constructs a new, empty bag with the specified initial capacity
 	 * and default load factor, which is 0.75.
@@ -112,7 +112,7 @@
 	public HashBag(int initialCapacity) {
 		this(initialCapacity, 0.75f);
 	}
-	
+
 	/**
 	 * Constructs a new, empty bag with
 	 * the specified initial capacity and the specified load factor.
@@ -122,7 +122,6 @@
 	 * @throws IllegalArgumentException if the initial capacity is less
 	 *     than zero, or if the load factor is nonpositive.
 	 */
-	@SuppressWarnings("unchecked")
 	public HashBag(int initialCapacity, float loadFactor) {
 		if (initialCapacity < 0) {
 			throw new IllegalArgumentException("Illegal Initial Capacity: " + initialCapacity);
@@ -134,10 +133,10 @@
 			initialCapacity = 1;
 		}
 		this.loadFactor = loadFactor;
-		this.table = new Entry[initialCapacity];
+		this.table = this.buildTable(initialCapacity);
 		this.threshold = (int) (initialCapacity * loadFactor);
 	}
-	
+
 	/**
 	 * Constructs a new bag containing the elements in the specified
 	 * collection. The capacity of the bag is
@@ -150,7 +149,7 @@
 		this(Math.max(2*c.size(), 11));
 		this.addAll(c);
 	}
-	
+
 	/**
 	 * This implementation simply returns the maintained count.
 	 */
@@ -158,7 +157,7 @@
 	public int size() {
 		return this.count;
 	}
-	
+
 	/**
 	 * This implementation simply compares the maintained count to zero.
 	 */
@@ -166,7 +165,7 @@
 	public boolean isEmpty() {
 		return this.count == 0;
 	}
-	
+
 	/**
 	 * This implementation searches for the object in the hash table by calculating
 	 * the object's hash code and examining the entries in the corresponding hash
@@ -192,10 +191,7 @@
 		}
 		return false;
 	}
-	
-	/**
-	 * Return the number of times the specified object occurs in the bag.
-	 */	
+
 	public int count(Object o) {
 		Entry<E>[] tab = this.table;
 		if (o == null) {
@@ -215,50 +211,63 @@
 		}
 		return 0;
 	}
-	
+
 	/**
 	 * Rehashes the contents of this bag into a new hash table
 	 * with a larger capacity. This method is called when the
 	 * number of different elements in this map exceeds its
 	 * capacity and load factor.
 	 */
-	@SuppressWarnings("unchecked")
 	private void rehash() {
 		Entry<E>[] oldMap = this.table;
 		int oldCapacity = oldMap.length;
-	
+
 		int newCapacity = oldCapacity * 2 + 1;
-		Entry<E>[] newMap = new Entry[newCapacity];
-	
+		Entry<E>[] newTable = this.buildTable(newCapacity);
+
 		this.modCount++;
 		this.threshold = (int) (newCapacity * this.loadFactor);
-		this.table = newMap;
-	
+		this.table = newTable;
+
 		for (int i = oldCapacity; i-- > 0; ) {
 			for (Entry<E> old = oldMap[i]; old != null; ) {
 				Entry<E> e = old;
 				old = old.next;
-	
+
 				int index = (e.hash & 0x7FFFFFFF) % newCapacity;
-				e.next = newMap[index];
-				newMap[index] = e;
+				e.next = newTable[index];
+				newTable[index] = e;
 			}
 		}
 	}
-	
+
+	@SuppressWarnings("unchecked")
+	private Entry<E>[] buildTable(int capacity) {
+		return new Entry[capacity];
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T> Entry<E> buildEntry(int hash, Object o, Entry<T> next) {
+		return new Entry(hash, o, next);
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T> Entry<E> buildEntry(int hash, Object o, int cnt, Entry<T> next) {
+		return new Entry(hash, o, cnt, next);
+	}
+
 	/**
 	 * This implementation searches for the object in the hash table by calculating
 	 * the object's hash code and examining the entries in the corresponding hash
 	 * table bucket.
 	 */
 	@Override
-	@SuppressWarnings("unchecked")
 	public boolean add(E o) {
 		this.modCount++;
 		Entry<E>[] tab = this.table;
 		int hash = 0;
 		int index = 0;
-	
+
 		// if the object is already in the bag, simply bump its count
 		if (o == null) {
 			for (Entry<E> e = tab[0]; e != null; e = e.next) {
@@ -279,22 +288,72 @@
 				}
 			}
 		}
-	
+
 		// rehash the table if the threshold is exceeded
 		if (this.uniqueCount >= this.threshold) {
 			this.rehash();
 			tab = this.table;
 			index = (hash & 0x7FFFFFFF) % tab.length;
 		}
-	
+
 		// create the new entry and put it in the table
-		Entry<E> e = new Entry(hash, o, tab[index]);
+		Entry<E> e = this.buildEntry(hash, o, tab[index]);
 		tab[index] = e;
 		this.count++;
 		this.uniqueCount++;
 		return true;
 	}
-	
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	public boolean add(E o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		this.modCount++;
+		Entry<E>[] tab = this.table;
+		int hash = 0;
+		int index = 0;
+
+		// if the object is already in the bag, simply bump its count
+		if (o == null) {
+			for (Entry<E> e = tab[0]; e != null; e = e.next) {
+				if (e.object == null) {
+					e.count += cnt;
+					this.count += cnt;
+					return true;
+				}
+			}
+		} else {
+			hash = o.hashCode();
+			index = (hash & 0x7FFFFFFF) % tab.length;
+			for (Entry<E> e = tab[index]; e != null; e = e.next) {
+				if ((e.hash == hash) && o.equals(e.object)) {
+					e.count += cnt;
+					this.count += cnt;
+					return true;
+				}
+			}
+		}
+
+		// rehash the table if the threshold is exceeded
+		if (this.uniqueCount >= this.threshold) {
+			this.rehash();
+			tab = this.table;
+			index = (hash & 0x7FFFFFFF) % tab.length;
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, cnt, tab[index]);
+		tab[index] = e;
+		this.count += cnt;
+		this.uniqueCount++;
+		return true;
+	}
+
 	/**
 	 * This implementation searches for the object in the hash table by calculating
 	 * the object's hash code and examining the entries in the corresponding hash
@@ -342,10 +401,65 @@
 				}
 			}
 		}
-	
+
 		return false;
 	}
-	
+
+	/**
+	 * This implementation searches for the object in the hash table by calculating
+	 * the object's hash code and examining the entries in the corresponding hash
+	 * table bucket.
+	 */
+	public boolean remove(Object o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		Entry<E>[] tab = this.table;
+		if (o == null) {
+			for (Entry<E> e = tab[0], prev = null; e != null; prev = e, e = e.next) {
+				if (e.object == null) {
+					this.modCount++;
+					int cnt2 = (cnt < e.count) ? cnt : e.count;
+					e.count -= cnt2;
+					// if we are removing the last element(s), remove the entry from the table
+					if (e.count == 0) {
+						if (prev == null) {
+							tab[0] = e.next;
+						} else {
+							prev.next = e.next;
+						}
+						this.uniqueCount--;
+					}
+					this.count -= cnt2;
+					return true;
+				}
+			}
+		} else {
+			int hash = o.hashCode();
+			int index = (hash & 0x7FFFFFFF) % tab.length;
+			for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
+				if ((e.hash == hash) && o.equals(e.object)) {
+					this.modCount++;
+					int cnt2 = (cnt < e.count) ? cnt : e.count;
+					e.count -= cnt2;
+					// if we are removing the last element(s), remove the entry from the table
+					if (e.count == 0) {
+						if (prev == null) {
+							tab[index] = e.next;
+						} else {
+							prev.next = e.next;
+						}
+						this.uniqueCount--;
+					}
+					this.count -= cnt2;
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
 	/**
 	 * This implementation simply clears out all of the hash table buckets.
 	 */
@@ -359,7 +473,7 @@
 		this.count = 0;
 		this.uniqueCount = 0;
 	}
-	
+
 	/**
 	 * Returns a shallow copy of this bag: the elements
 	 * themselves are not cloned.
@@ -367,14 +481,14 @@
 	 * @return a shallow copy of this bag.
 	 */
 	@Override
-	@SuppressWarnings("unchecked")
 	public HashBag<E> clone() {
 		try {
+			@SuppressWarnings("unchecked")
 			HashBag<E> clone = (HashBag<E>) super.clone();
-			clone.table = new Entry[this.table.length];
+			clone.table = this.buildTable(this.table.length);
 			for (int i = this.table.length; i-- > 0; ) {
 				clone.table[i] = (this.table[i] == null) 
-						? null : (Entry) this.table[i].clone();
+						? null : (Entry<E>) this.table[i].clone();
 			}
 			clone.modCount = 0;
 			return clone;
@@ -382,7 +496,7 @@
 			throw new InternalError();
 		}
 	}
-	
+
 	/**
 	 * Hash table collision list entry.
 	 */
@@ -391,31 +505,34 @@
 		E object;
 		int count;
 		Entry<E> next;
-	
+
 		Entry(int hash, E object, Entry<E> next) {
 			this(hash, object, 1, next);
 		}
-	
-		private Entry(int hash, E object, int count, Entry<E> next) {
+
+		Entry(int hash, E object, int count, Entry<E> next) {
 			this.hash = hash;
 			this.object = object;
 			this.count = count;
 			this.next = next;
 		}
-	
+
+		/**
+		 * Cascade the clone to all the entries in the same bucket.
+		 */
 		@Override
 		@SuppressWarnings("unchecked")
 		protected Entry<E> clone() {
 			return new Entry(this.hash, this.object, this.count,
 					(this.next == null ? null : this.next.clone()));
 		}
-	
+
 		@Override
 		public String toString() {
 			return this.object + "=>" + this.count;
 		}
 	}
-	
+
 	@Override
 	@SuppressWarnings("unchecked")
 	public Iterator<E> iterator() {
@@ -425,11 +542,6 @@
 		return new HashIterator();
 	}
 
-	/**
-	 * Return an iterator that returns each item in the bag
-	 * once and only once, irrespective of how many times
-	 * the item was added to the bag.
-	 */
 	@SuppressWarnings("unchecked")
 	public Iterator<E> uniqueIterator() {
 		if (this.count == 0) {
@@ -437,13 +549,13 @@
 		}
 		return new UniqueIterator();
 	}
-	
+
 	/**
 	 * Empty iterator that does just about nothing.
 	 */
 	@SuppressWarnings("unchecked")
 	private static final Iterator EMPTY_ITERATOR = new EmptyIterator();
-	
+
 	@SuppressWarnings("unchecked")
 	private static class EmptyIterator implements Iterator {
 
@@ -454,16 +566,16 @@
 		public boolean hasNext() {
 			return false;
 		}
-	
+
 		public Object next() {
 			throw new NoSuchElementException();
 		}
-	
+
 		public void remove() {
 			throw new IllegalStateException();
 		}
 	}
-	
+
 	private class HashIterator implements Iterator<E> {
 		Entry<E>[] localTable = HashBag.this.table;
 		int index = this.localTable.length;	// start at the end of the table
@@ -473,7 +585,7 @@
 
 		/**
 		 * The modCount value that the iterator believes that the backing
-		 * Bag should have. If this expectation is violated, the iterator
+		 * bag should have. If this expectation is violated, the iterator
 		 * has detected a concurrent modification.
 		 */
 		private int expectedModCount = HashBag.this.modCount;
@@ -555,8 +667,8 @@
 		}
 
 	}
-	
-	
+
+
 	private class UniqueIterator implements Iterator<E> {
 		Entry<E>[] localTable = HashBag.this.table;
 		int index = this.localTable.length;	// start at the end of the table
@@ -565,7 +677,7 @@
 
 		/**
 		 * The modCount value that the iterator believes that the backing
-		 * Bag should have. If this expectation is violated, the iterator
+		 * bag should have. If this expectation is violated, the iterator
 		 * has detected a concurrent modification.
 		 */
 		private int expectedModCount = HashBag.this.modCount;
@@ -637,10 +749,9 @@
 		}
 
 	}
-	
-	
+
+
 	@Override
-	@SuppressWarnings("unchecked")
 	public boolean equals(Object o) {
 		if (o == this) {
 			return true;
@@ -648,6 +759,7 @@
 		if ( ! (o instanceof Bag)) {
 			return false;
 		}
+		@SuppressWarnings("unchecked")
 		Bag<E> b = (Bag<E>) o;
 		if (b.size() != this.size()) {
 			return false;
@@ -660,7 +772,7 @@
 		}
 		return clone.isEmpty();
 	}
-	
+
 	@Override
 	public int hashCode() {
 		int h = 0;
@@ -672,7 +784,7 @@
 		}
 		return h;
 	}
-	
+
 	/**
 	 * Save the state of this bag to a stream (i.e. serialize it).
 	 *
@@ -685,10 +797,10 @@
 				throws java.io.IOException {
 		// write out the threshold, load factor, and any hidden stuff
 		s.defaultWriteObject();
-	
+
 		// write out number of buckets
 		s.writeInt(this.table.length);
-	
+
 		// write out number of unique elements
 		s.writeInt(this.uniqueCount);
 
@@ -702,31 +814,29 @@
 			}
 		}
 	}
-	
+
 	private static final long serialVersionUID = 1L;
-	
+
 	/**
 	 * Reconstitute the bag from a stream (i.e. deserialize it).
 	 */
-	@SuppressWarnings("unchecked")
 	private synchronized void readObject(java.io.ObjectInputStream s)
 				throws java.io.IOException, ClassNotFoundException {
 		// read in the threshold, loadfactor, and any hidden stuff
 		s.defaultReadObject();
-	
+
 		// read in number of buckets and allocate the bucket array
-		this.table = new Entry[s.readInt()];
-	
+		this.table = this.buildTable(s.readInt());
+
 		// read in number of unique elements
 		int unique = s.readInt();
-	
+
 		// read the elements and counts, and put the elements in the bag
 		for (int i = 0; i < unique; i++) {
+			@SuppressWarnings("unchecked")
 			E element = (E) s.readObject();
 			int elementCount = s.readInt();
-			for (int j = 0; j < elementCount; j++) {
-				this.add(element);
-			}
+			this.add(element, elementCount);
 		}
 	}
 
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IdentityHashBag.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IdentityHashBag.java
new file mode 100644
index 0000000..25023fd
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/IdentityHashBag.java
@@ -0,0 +1,814 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * This class implements the <code>Bag</code> interface with a
+ * hash table, using object-identity in place of object-equality when
+ * comparing elements. In other words, in an <code>IdentityHashBag</code>,
+ * two objects <code>k1</code> and <code>k2</code> are considered
+ * equal if and only if <code>(k1 == k2)</code>. (In normal <code>Bag</code>
+ * implementations (like <code>HashBag</code>) two objects <code>k1</code>
+ * and <code>k2</code> are considered equal if and only if
+ * <code>(k1 == null ? k2 == null : k1.equals(k2))</code>.)
+ * <p>
+ * <b>
+ * This class is <i>not</i> a general-purpose <code>Bag</code>
+ * implementation! While this class implements the <code>Bag</code> interface, it
+ * intentionally violates <code>Bag's</code> general contract, which mandates the
+ * use of the <code>equals</code> method when comparing objects. This class is
+ * designed for use only in the rare cases wherein object-identity
+ * semantics are required.
+ * </b>
+ * <p>
+ * This class makes no guarantees as to the iteration order of
+ * the bag's elements; in particular, it does not guarantee that the order
+ * will remain constant over time. This class permits the <code>null</code>
+ * element.
+ * <p>
+ * This class offers constant time performance for the basic operations
+ * (<code>add</code>, <code>remove</code>, <code>contains</code> and
+ * <code>size</code>), assuming the system identity hash function
+ * ({@link System#identityHashCode(Object)}) disperses elements properly
+ * among the buckets. Iterating over this bag requires time
+ * proportional to the sum of the bag's size (the number of elements) plus the
+ * "capacity" of the backing hash table (the number of buckets). Thus, it is
+ * important not to set the initial capacity too high (or the load factor too
+ * low) if iteration performance is important.
+ * <p>
+ * <b>Note that this implementation is not synchronized.</b> If multiple
+ * threads access a bag concurrently, and at least one of the threads modifies
+ * the bag, it <i>must</i> be synchronized externally. This is typically
+ * accomplished by synchronizing on some object that naturally encapsulates
+ * the bag. If no such object exists, the bag should be "wrapped" using the
+ * <code>Collections.synchronizedCollection</code> method. This is
+ * best done at creation time, to prevent accidental unsynchronized access
+ * to the bag:
+ * <pre>
+ * Collection c = Collections.synchronizedCollection(new IdentityHashBag(...));
+ * </pre>
+ * <p>
+ * The iterators returned by this class's <code>iterator</code> method are
+ * <i>fail-fast</i>: if the bag is modified at any time after the iterator is
+ * created, in any way except through the iterator's own <code>remove</code>
+ * method, the iterator throws a <code>ConcurrentModificationException</code>.
+ * Thus, in the face of concurrent modification, the iterator fails quickly
+ * and cleanly, rather than risking arbitrary, non-deterministic behavior at
+ * an undetermined time in the future.
+ * 
+ * @see	Collections#synchronizedCollection(Collection)
+ */
+
+public class IdentityHashBag<E> extends AbstractCollection<E>
+			implements Bag<E>, Cloneable, Serializable {
+
+	/** The hash table. */
+	transient Entry<E>[] table;
+
+	/** The total number of entries in the bag. */
+	transient int count = 0;
+
+	/** The number of unique entries in the bag. */
+	transient int uniqueCount = 0;
+
+	/**
+	 * The hash table is rehashed when its size exceeds this threshold. (The
+	 * value of this field is (int)(capacity * loadFactor).)
+	 *
+	 * @serial
+	 */
+	private int threshold;
+
+	/**
+	 * The load factor for the hash table.
+	 *
+	 * @serial
+	 */
+	private float loadFactor;
+
+	/**
+	 * The number of times this bag has been structurally modified.
+	 * Structural modifications are those that change the number of entries in
+	 * the bag or otherwise modify its internal structure (e.g. rehash).
+	 * This field is used to make iterators on this bag fail-fast.
+	 *
+	 * @see java.util.ConcurrentModificationException
+	 */
+	transient int modCount = 0;
+
+	/**
+	 * Constructs a new, empty bag with the
+	 * default capacity, which is 11, and load factor, which is 0.75.
+	 */
+	public IdentityHashBag() {
+		this(11, 0.75f);
+	}
+
+	/**
+	 * Constructs a new, empty bag with the specified initial capacity
+	 * and default load factor, which is 0.75.
+	 *
+	 * @param initialCapacity the initial capacity of the backing map.
+	 * @throws IllegalArgumentException if the initial capacity is less
+	 *     than zero.
+	 */
+	public IdentityHashBag(int initialCapacity) {
+		this(initialCapacity, 0.75f);
+	}
+
+	/**
+	 * Constructs a new, empty bag with
+	 * the specified initial capacity and the specified load factor.
+	 *
+	 * @param initialCapacity the initial capacity of the backing map.
+	 * @param loadFactor the load factor of the backing map.
+	 * @throws IllegalArgumentException if the initial capacity is less
+	 *     than zero, or if the load factor is nonpositive.
+	 */
+	public IdentityHashBag(int initialCapacity, float loadFactor) {
+		if (initialCapacity < 0) {
+			throw new IllegalArgumentException("Illegal Initial Capacity: " + initialCapacity);
+		}
+		if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
+			throw new IllegalArgumentException("Illegal Load factor: " + loadFactor);
+		}
+		if (initialCapacity == 0) {
+			initialCapacity = 1;
+		}
+		this.loadFactor = loadFactor;
+		this.table = this.buildTable(initialCapacity);
+		this.threshold = (int) (initialCapacity * loadFactor);
+	}
+
+	/**
+	 * Constructs a new bag containing the elements in the specified
+	 * collection. The capacity of the bag is
+	 * twice the size of the specified collection or 11 (whichever is
+	 * greater), and the default load factor, which is 0.75, is used.
+	 *
+	 * @param c the collection whose elements are to be placed into this bag.
+	 */
+	public IdentityHashBag(Collection<? extends E> c) {
+		this(Math.max(2*c.size(), 11));
+		this.addAll(c);
+	}
+
+	/**
+	 * This implementation simply returns the maintained count.
+	 */
+	@Override
+	public int size() {
+		return this.count;
+	}
+
+	/**
+	 * This implementation simply compares the maintained count to zero.
+	 */
+	@Override
+	public boolean isEmpty() {
+		return this.count == 0;
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by
+	 * calculating the object's identity hash code and examining the
+	 * entries in the corresponding hash table bucket.
+	 */
+	@Override
+	public boolean contains(Object o) {
+		Entry<E>[] tab = this.table;
+		int hash = System.identityHashCode(o);
+		int index = (hash & 0x7FFFFFFF) % tab.length;
+		for (Entry<E> e = tab[index]; e != null; e = e.next) {
+			if ((e.hash == hash) && (e.object == o)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public int count(Object o) {
+		Entry<E>[] tab = this.table;
+		int hash = System.identityHashCode(o);
+		int index = (hash & 0x7FFFFFFF) % tab.length;
+		for (Entry<E> e = tab[index]; e != null; e = e.next) {
+			if ((e.hash == hash) && (e.object == o)) {
+				return e.count;
+			}
+		}
+		return 0;
+	}
+
+	/**
+	 * Rehashes the contents of this bag into a new hash table
+	 * with a larger capacity. This method is called when the
+	 * number of different elements in this map exceeds its
+	 * capacity and load factor.
+	 */
+	private void rehash() {
+		Entry<E>[] oldMap = this.table;
+		int oldCapacity = oldMap.length;
+
+		int newCapacity = oldCapacity * 2 + 1;
+		Entry<E>[] newTable = this.buildTable(newCapacity);
+
+		this.modCount++;
+		this.threshold = (int) (newCapacity * this.loadFactor);
+		this.table = newTable;
+
+		for (int i = oldCapacity; i-- > 0; ) {
+			for (Entry<E> old = oldMap[i]; old != null; ) {
+				Entry<E> e = old;
+				old = old.next;
+
+				int index = (e.hash & 0x7FFFFFFF) % newCapacity;
+				e.next = newTable[index];
+				newTable[index] = e;
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private Entry<E>[] buildTable(int capacity) {
+		return new Entry[capacity];
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T> Entry<E> buildEntry(int hash, Object o, Entry<T> next) {
+		return new Entry(hash, o, next);
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T> Entry<E> buildEntry(int hash, Object o, int cnt, Entry<T> next) {
+		return new Entry(hash, o, cnt, next);
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by
+	 * calculating the object's identity hash code and examining the
+	 * entries in the corresponding hash table bucket.
+	 */
+	@Override
+	public boolean add(E o) {
+		this.modCount++;
+		Entry<E>[] tab = this.table;
+		int hash = 0;
+		int index = 0;
+
+		// if the object is already in the bag, simply bump its count
+		hash = System.identityHashCode(o);
+		index = (hash & 0x7FFFFFFF) % tab.length;
+		for (Entry<E> e = tab[index]; e != null; e = e.next) {
+			if ((e.hash == hash) && (e.object == o)) {
+				e.count++;
+				this.count++;
+				return true;
+			}
+		}
+
+		// rehash the table if the threshold is exceeded
+		if (this.uniqueCount >= this.threshold) {
+			this.rehash();
+			tab = this.table;
+			index = (hash & 0x7FFFFFFF) % tab.length;
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, tab[index]);
+		tab[index] = e;
+		this.count++;
+		this.uniqueCount++;
+		return true;
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by
+	 * calculating the object's identity hash code and examining the
+	 * entries in the corresponding hash table bucket.
+	 */
+	public boolean add(E o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		this.modCount++;
+		Entry<E>[] tab = this.table;
+		int hash = 0;
+		int index = 0;
+
+		// if the object is already in the bag, simply bump its count
+		hash = System.identityHashCode(o);
+		index = (hash & 0x7FFFFFFF) % tab.length;
+		for (Entry<E> e = tab[index]; e != null; e = e.next) {
+			if ((e.hash == hash) && (e.object == o)) {
+				e.count += cnt;
+				this.count += cnt;
+				return true;
+			}
+		}
+
+		// rehash the table if the threshold is exceeded
+		if (this.uniqueCount >= this.threshold) {
+			this.rehash();
+			tab = this.table;
+			index = (hash & 0x7FFFFFFF) % tab.length;
+		}
+
+		// create the new entry and put it in the table
+		Entry<E> e = this.buildEntry(hash, o, cnt, tab[index]);
+		tab[index] = e;
+		this.count += cnt;
+		this.uniqueCount++;
+		return true;
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by
+	 * calculating the object's identity hash code and examining the
+	 * entries in the corresponding hash table bucket.
+	 */
+	@Override
+	public boolean remove(Object o) {
+		Entry<E>[] tab = this.table;
+		int hash = System.identityHashCode(o);
+		int index = (hash & 0x7FFFFFFF) % tab.length;
+		for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
+			if ((e.hash == hash) && (e.object == o)) {
+				this.modCount++;
+				e.count--;
+				// if we are removing the last one, remove the entry from the table
+				if (e.count == 0) {
+					if (prev == null) {
+						tab[index] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					this.uniqueCount--;
+				}
+				this.count--;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * This implementation searches for the object in the hash table by
+	 * calculating the object's identity hash code and examining the
+	 * entries in the corresponding hash table bucket.
+	 */
+	public boolean remove(Object o, int cnt) {
+		if (cnt <= 0) {
+			return false;
+		}
+		Entry<E>[] tab = this.table;
+		int hash = System.identityHashCode(o);
+		int index = (hash & 0x7FFFFFFF) % tab.length;
+		for (Entry<E> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
+			if ((e.hash == hash) && (e.object == o)) {
+				this.modCount++;
+				int cnt2 = (cnt < e.count) ? cnt : e.count;
+				e.count -= cnt2;
+				// if we are removing the last element(s), remove the entry from the table
+				if (e.count == 0) {
+					if (prev == null) {
+						tab[index] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					this.uniqueCount--;
+				}
+				this.count -= cnt2;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * This implementation uses object-identity to determine whether
+	 * specified collection contains a particular element.
+	 */
+	@Override
+	public boolean removeAll(Collection<?> c) {
+		return super.removeAll(this.buildIdentityHashBag(c));
+	}
+
+	/**
+	 * This implementation uses object-identity to determine whether
+	 * specified collection contains a particular element.
+	 */
+	@Override
+	public boolean retainAll(Collection<?> c) {
+		return super.retainAll(this.buildIdentityHashBag(c));
+	}
+
+	@SuppressWarnings("unchecked")
+	private Collection<?> buildIdentityHashBag(Collection<?> c) {
+		return new IdentityHashBag(c);
+	}
+
+	/**
+	 * This implementation simply clears out all of the hash table buckets.
+	 */
+	@Override
+	public void clear() {
+		Entry<E>[] tab = this.table;
+		this.modCount++;
+		for (int i = tab.length; --i >= 0; ) {
+			tab[i] = null;
+		}
+		this.count = 0;
+		this.uniqueCount = 0;
+	}
+
+	/**
+	 * Returns a shallow copy of this bag: the elements
+	 * themselves are not cloned.
+	 *
+	 * @return a shallow copy of this bag.
+	 */
+	@Override
+	public IdentityHashBag<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			IdentityHashBag<E> clone = (IdentityHashBag<E>) super.clone();
+			clone.table = this.buildTable(this.table.length);
+			for (int i = this.table.length; i-- > 0; ) {
+				clone.table[i] = (this.table[i] == null) 
+						? null : (Entry<E>) this.table[i].clone();
+			}
+			clone.modCount = 0;
+			return clone;
+		} catch (CloneNotSupportedException e) {
+			throw new InternalError();
+		}
+	}
+
+	/**
+	 * Hash table collision list entry.
+	 */
+	private static class Entry<E> {
+		int hash;
+		E object;
+		int count;
+		Entry<E> next;
+
+		Entry(int hash, E object, Entry<E> next) {
+			this(hash, object, 1, next);
+		}
+
+		Entry(int hash, E object, int count, Entry<E> next) {
+			this.hash = hash;
+			this.object = object;
+			this.count = count;
+			this.next = next;
+		}
+
+		/**
+		 * Cascade the clone to all the entries in the same bucket.
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		protected Entry<E> clone() {
+			return new Entry(this.hash, this.object, this.count,
+					(this.next == null ? null : this.next.clone()));
+		}
+
+		@Override
+		public String toString() {
+			return this.object + "=>" + this.count;
+		}
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Iterator<E> iterator() {
+		if (this.count == 0) {
+			return EMPTY_ITERATOR;
+		}
+		return new HashIterator();
+	}
+
+	/**
+	 * Return an iterator that returns each item in the bag
+	 * once and only once, irrespective of how many times
+	 * the item was added to the bag.
+	 */
+	@SuppressWarnings("unchecked")
+	public Iterator<E> uniqueIterator() {
+		if (this.count == 0) {
+			return EMPTY_ITERATOR;
+		}
+		return new UniqueIterator();
+	}
+
+	/**
+	 * Empty iterator that does just about nothing.
+	 */
+	@SuppressWarnings("unchecked")
+	private static final Iterator EMPTY_ITERATOR = new EmptyIterator();
+
+	@SuppressWarnings("unchecked")
+	private static class EmptyIterator implements Iterator {
+
+		EmptyIterator() {
+			super();
+		}
+
+		public boolean hasNext() {
+			return false;
+		}
+
+		public Object next() {
+			throw new NoSuchElementException();
+		}
+
+		public void remove() {
+			throw new IllegalStateException();
+		}
+	}
+
+	private class HashIterator implements Iterator<E> {
+		Entry<E>[] localTable = IdentityHashBag.this.table;
+		int index = this.localTable.length;	// start at the end of the table
+		Entry<E> nextEntry = null;
+		int nextEntryCount = 0;
+		Entry<E> lastReturnedEntry = null;
+
+		/**
+		 * The modCount value that the iterator believes that the backing
+		 * bag should have. If this expectation is violated, the iterator
+		 * has detected a concurrent modification.
+		 */
+		private int expectedModCount = IdentityHashBag.this.modCount;
+
+		HashIterator() {
+			super();
+		}
+
+		public boolean hasNext() {
+			Entry<E> e = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = this.localTable;
+			// Use locals for faster loop iteration
+			while ((e == null) && (i > 0)) {
+				e = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = e;
+			this.index = i;
+			return e != null;
+		}
+
+		public E next() {
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E> et = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = this.localTable;
+			// Use locals for faster loop iteration
+			while ((et == null) && (i > 0)) {
+				et = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = et;
+			this.index = i;
+			if (et == null) {
+				throw new NoSuchElementException();
+			}
+			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
+			this.nextEntryCount++;
+			if (this.nextEntryCount == e.count) {
+				this.nextEntry = e.next;
+				this.nextEntryCount = 0;
+			}
+			return e.object;
+		}
+
+		public void remove() {
+			if (this.lastReturnedEntry == null) {
+				throw new IllegalStateException();
+			}
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E>[] tab = this.localTable;
+			int slot = (this.lastReturnedEntry.hash & 0x7FFFFFFF) % tab.length;
+			for (Entry<E> e = tab[slot], prev = null; e != null; prev = e, e = e.next) {
+				if (e == this.lastReturnedEntry) {
+					IdentityHashBag.this.modCount++;
+					this.expectedModCount++;
+					e.count--;
+					if (e.count == 0) {
+						// if we are removing the last one, remove the entry from the table
+						if (prev == null) {
+							tab[slot] = e.next;
+						} else {
+							prev.next = e.next;
+						}
+						IdentityHashBag.this.uniqueCount--;
+					} else {
+						// slide back the count to account for the just-removed element
+						this.nextEntryCount--;
+					}
+					IdentityHashBag.this.count--;
+					this.lastReturnedEntry = null;	// it cannot be removed again
+					return;
+				}
+			}
+			throw new ConcurrentModificationException();
+		}
+	}
+
+	private class UniqueIterator implements Iterator<E> {
+		Entry<E>[] localTable = IdentityHashBag.this.table;
+		int index = this.localTable.length;	// start at the end of the table
+		Entry<E> nextEntry = null;
+		Entry<E> lastReturnedEntry = null;
+
+		/**
+		 * The modCount value that the iterator believes that the backing
+		 * bag should have. If this expectation is violated, the iterator
+		 * has detected a concurrent modification.
+		 */
+		private int expectedModCount = IdentityHashBag.this.modCount;
+
+		UniqueIterator() {
+			super();
+		}
+
+		public boolean hasNext() {
+			Entry<E> e = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = this.localTable;
+			// Use locals for faster loop iteration
+			while ((e == null) && (i > 0)) {
+				e = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = e;
+			this.index = i;
+			return e != null;
+		}
+
+		public E next() {
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E> et = this.nextEntry;
+			int i = this.index;
+			Entry<E>[] tab = this.localTable;
+			// Use locals for faster loop iteration
+			while ((et == null) && (i > 0)) {
+				et = tab[--i];		// move backwards through the table
+			}
+			this.nextEntry = et;
+			this.index = i;
+			if (et == null) {
+				throw new NoSuchElementException();
+			}
+			Entry<E> e = this.lastReturnedEntry = this.nextEntry;
+			this.nextEntry = e.next;
+			return e.object;
+		}
+
+		public void remove() {
+			if (this.lastReturnedEntry == null) {
+				throw new IllegalStateException();
+			}
+			if (IdentityHashBag.this.modCount != this.expectedModCount) {
+				throw new ConcurrentModificationException();
+			}
+			Entry<E>[] tab = this.localTable;
+			int slot = (this.lastReturnedEntry.hash & 0x7FFFFFFF) % tab.length;
+			for (Entry<E> e = tab[slot], prev = null; e != null; prev = e, e = e.next) {
+				if (e == this.lastReturnedEntry) {
+					IdentityHashBag.this.modCount++;
+					this.expectedModCount++;
+					// remove the entry from the table
+					if (prev == null) {
+						tab[slot] = e.next;
+					} else {
+						prev.next = e.next;
+					}
+					IdentityHashBag.this.uniqueCount--;
+					IdentityHashBag.this.count -= this.lastReturnedEntry.count;
+					this.lastReturnedEntry = null;	// it cannot be removed again
+					return;
+				}
+			}
+			throw new ConcurrentModificationException();
+		}
+
+	}
+
+
+	@Override
+	public boolean equals(Object o) {
+		if (o == this) {
+			return true;
+		} else if (o instanceof IdentityHashBag) {
+			@SuppressWarnings("unchecked")
+			IdentityHashBag<E> b = (IdentityHashBag<E>) o;
+			if (b.size() != this.size()) {
+				return false;
+			}
+			IdentityHashBag<E> clone = this.clone();
+			for (E e : b) {
+				if ( ! clone.remove(e)) {
+					return false;
+				}
+			}
+			return clone.isEmpty();
+		} else if (o instanceof Bag) {
+			// hmmm...
+			return this.buildBag().equals(o);
+		} else {
+			return false;
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private Bag<E> buildBag() {
+		return new HashBag(this);
+	}
+
+	@Override
+	public int hashCode() {
+		int h = 0;
+		for (E e : this) {
+			h += System.identityHashCode(e);
+		}
+		return h;
+	}
+
+	/**
+	 * Save the state of this bag to a stream (i.e. serialize it).
+	 *
+	 * @serialData Emit the capacity of the bag (int),
+	 *     followed by the number of unique elements in the bag (int),
+	 *     followed by all of the bag's elements (each an Object) and
+	 *     their counts (each an int), in no particular order.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s)
+				throws java.io.IOException {
+		// write out the threshold, load factor, and any hidden stuff
+		s.defaultWriteObject();
+
+		// write out number of buckets
+		s.writeInt(this.table.length);
+
+		// write out number of unique elements
+		s.writeInt(this.uniqueCount);
+
+		Entry<E>[] tab = this.table;
+		// write out elements and counts (alternating)
+		for (Entry<E> entry : tab) {
+			while (entry != null) {
+				s.writeObject(entry.object);
+				s.writeInt(entry.count);
+				entry = entry.next;
+			}
+		}
+	}
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Reconstitute the bag from a stream (i.e. deserialize it).
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s)
+				throws java.io.IOException, ClassNotFoundException {
+		// read in the threshold, loadfactor, and any hidden stuff
+		s.defaultReadObject();
+
+		// read in number of buckets and allocate the bucket array
+		this.table = this.buildTable(s.readInt());
+
+		// read in number of unique elements
+		int unique = s.readInt();
+
+		// read the elements and counts, and put the elements in the bag
+		for (int i = 0; i < unique; i++) {
+			@SuppressWarnings("unchecked")
+			E element = (E) s.readObject();
+			int elementCount = s.readInt();
+			for (int j = 0; j < elementCount; j++) {
+				this.add(element);
+			}
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java
index 23c4f6d..900bfd2 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/JDBCTools.java
@@ -124,7 +124,7 @@
 		addJDBCToJavaTypeMappingTo(Types.LONGVARBINARY, byte[].class, mappings);
 		addJDBCToJavaTypeMappingTo(Types.LONGVARCHAR, java.lang.String.class, mappings);
 		// not sure why this is defined in java.sql.Types
-//		addJDBCMappingTo(Types.NULL, java.lang.Object.class, mappings);
+//		addJDBCToJavaTypeMappingTo(Types.NULL, java.lang.Object.class, mappings);
 		addJDBCToJavaTypeMappingTo(Types.NUMERIC, java.math.BigDecimal.class, mappings);
 		addJDBCToJavaTypeMappingTo(Types.OTHER, java.lang.Object.class, mappings);	// ???
 		addJDBCToJavaTypeMappingTo(Types.REAL, float.class, mappings);
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStack.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStack.java
new file mode 100644
index 0000000..e45bea5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleStack.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+import java.io.Serializable;
+import java.util.EmptyStackException;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+/**
+ * Straightforward implementation of the Stack interface.
+ */
+public class SimpleStack<E>
+	implements Stack<E>, Cloneable, Serializable
+{
+	private LinkedList<E> elements;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct an empty stack.
+	 */
+	public SimpleStack() {
+		super();
+		this.elements = new LinkedList<E>();
+	}
+
+
+	// ********** Stack implementation **********
+
+	public void push(E o) {
+		this.elements.addLast(o);
+	}
+
+	public E pop() {
+		try {
+			return this.elements.removeLast();
+		} catch (NoSuchElementException ex) {
+			throw new EmptyStackException();
+		}
+	}
+
+	public E peek() {
+		try {
+			return this.elements.getLast();
+		} catch (NoSuchElementException ex) {
+			throw new EmptyStackException();
+		}
+	}
+
+	public boolean isEmpty() {
+		return this.elements.isEmpty();
+	}
+
+
+	// ********** Cloneable implementation **********
+
+	@Override
+	public SimpleStack<E> clone() {
+		try {
+			@SuppressWarnings("unchecked")
+			SimpleStack<E> clone = (SimpleStack<E>) super.clone();
+			@SuppressWarnings("unchecked")
+			LinkedList<E> ll = (LinkedList<E>) this.elements.clone();
+			clone.elements = ll;
+			return clone;
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Stack.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Stack.java
new file mode 100644
index 0000000..397d247
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/Stack.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+/**
+ * Interface defining the classic stack behavior,
+ * without the backdoors allowed by java.util.Stack.
+ * E is the type of elements contained by the Stack.
+ */
+public interface Stack<E> {
+
+	/**
+	 * "Push" the specified item on to the top of the stack.
+	 */
+	void push(E o);
+
+	/**
+	 * "Pop" an item from the top of the stack.
+	 */
+	E pop();
+
+	/**
+	 * Return the item on the top of the stack
+	 * without removing it from the stack.
+	 */
+	E peek();
+
+	/**
+	 * Return whether the stack is empty.
+	 */
+	boolean isEmpty();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedBoolean.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedBoolean.java
new file mode 100644
index 0000000..059e31b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedBoolean.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+import java.io.Serializable;
+
+/**
+ * This class provides synchronized access to a boolean value.
+ * It also provides protocol for suspending a thread until the
+ * boolean value is set to true or false, with optional time-outs.
+ */
+public class SynchronizedBoolean
+	implements Cloneable, Serializable
+{
+	/** Backing boolean. */
+	private boolean value;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a synchronized boolean with the specified initial value
+	 * and mutex.
+	 */
+	public SynchronizedBoolean(boolean value, Object mutex) {
+		super();
+		this.value = value;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Create a synchronized boolean with the specified initial value.
+	 */
+	public SynchronizedBoolean(boolean value) {
+		super();
+		this.value = value;
+		this.mutex = this;
+	}
+
+	/**
+	 * Create a synchronized boolean with an initial value of false
+	 * and specified mutex.
+	 */
+	public SynchronizedBoolean(Object mutex) {
+		this(false, mutex);
+	}
+
+	/**
+	 * Create a synchronized boolean with an initial value of false.
+	 */
+	public SynchronizedBoolean() {
+		this(false);
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Return the current boolean value.
+	 */
+	public boolean value() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	/**
+	 * Return whether the current boolean value is true.
+	 */
+	public boolean isTrue() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	/**
+	 * Return whether the current boolean value is false.
+	 */
+	public boolean isFalse() {
+		synchronized (this.mutex) {
+			return ! this.value;
+		}
+	}
+
+	/**
+	 * Set the boolean value. If the value changes, all waiting
+	 * threads are notified.
+	 */
+	public void setValue(boolean value) {
+		synchronized (this.mutex) {
+			if (this.value != value) {
+				this.value = value;
+				this.mutex.notifyAll();
+			}
+		}
+	}
+
+	/**
+	 * Set the boolean value to true. If the value changes, all waiting
+	 * threads are notified.
+	 */
+	public void setTrue() {
+		synchronized (this.mutex) {
+			this.setValue(true);
+		}
+	}
+
+	/**
+	 * Set the boolean value to false. If the value changes, all waiting
+	 * threads are notified.
+	 */
+	public void setFalse() {
+		synchronized (this.mutex) {
+			this.setValue(false);
+		}
+	}
+
+	/**
+	 * Return the object this object locks on while performing
+	 * its operations.
+	 */
+	public Object mutex() {
+		return this.mutex;
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the boolean value changes
+	 * to the specified value.
+	 */
+	public void waitUntilValueIs(boolean x) throws InterruptedException {
+		synchronized (this.mutex) {
+			while (this.value != x) {
+				this.mutex.wait();
+			}
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes to true.
+	 */
+	public void waitUntilTrue() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs(true);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes to false.
+	 */
+	public void waitUntilFalse() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs(false);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes to false,
+	 * then change it back to true and continue executing.
+	 */
+	public void waitToSetTrue() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilFalse();
+			this.setValue(true);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes to true,
+	 * then change it back to false and continue executing.
+	 */
+	public void waitToSetFalse() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilTrue();
+			this.setValue(false);
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the boolean value changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilValueIs(boolean x, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			if (timeout == 0L) {
+				this.waitUntilValueIs(x);	// wait indefinitely until notified
+				return true;	// if it ever comes back, the condition was met
+			}
+	
+			long stop = System.currentTimeMillis() + timeout;
+			long remaining = timeout;
+			while ((this.value != x) && (remaining > 0L)) {
+				this.mutex.wait(remaining);
+				remaining = stop - System.currentTimeMillis();
+			}
+			return (this.value == x);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes
+	 * to true or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilTrue(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIs(true, timeout);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes
+	 * to false or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilFalse(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIs(false, timeout);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes to false,
+	 * then change it back to true and continue executing. If the boolean
+	 * value does not change to false before the time-out, simply continue
+	 * executing without changing the value.
+	 * The time-out is specified in milliseconds. Return true if the value was
+	 * set to true; return false if a time-out occurred.
+	 */
+	public boolean waitToSetTrue(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilFalse(timeout);
+			if (success) {
+				this.setValue(true);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the boolean value changes to true,
+	 * then change it back to false and continue executing. If the boolean
+	 * value does not change to true before the time-out, simply continue
+	 * executing without changing the value.
+	 * The time-out is specified in milliseconds. Return true if the value was
+	 * set to false; return false if a time-out occurred.
+	 */
+	public boolean waitToSetFalse(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilTrue(timeout);
+			if (success) {
+				this.setValue(false);
+			}
+			return success;
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If the current thread is not interrupted, execute the specified command 
+	 * with the mutex locked. This is useful for initializing the value in another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.interrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public Object clone() {
+		try {
+			synchronized (this.mutex) {
+				return super.clone();
+			}
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof SynchronizedBoolean) {
+			return this.value() == ((SynchronizedBoolean) o).value();
+		}
+		return false;
+	}
+
+	@Override
+	public int hashCode() {
+		return this.value() ? 1 : 0;
+	}
+
+	@Override
+	public String toString() {
+		return String.valueOf(this.value());
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedObject.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedObject.java
new file mode 100644
index 0000000..e991bce
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedObject.java
@@ -0,0 +1,355 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+import java.io.Serializable;
+
+/**
+ * This class provides synchronized access to an object of type E.
+ * It also provides protocol for suspending a thread until the
+ * value is set to null or a non-null value, with optional time-outs.
+ */
+public class SynchronizedObject<E>
+	implements Cloneable, Serializable
+{
+	/** Backing value. */
+	private E value;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Create a synchronized object with the specified initial value
+	 * and mutex.
+	 */
+	public SynchronizedObject(E value, Object mutex) {
+		super();
+		this.value = value;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Create a synchronized object with the specified initial value.
+	 */
+	public SynchronizedObject(E value) {
+		super();
+		this.value = value;
+		this.mutex = this;
+	}
+
+	/**
+	 * Create a synchronized object with an initial value of null.
+	 */
+	public SynchronizedObject() {
+		this(null);
+	}
+
+
+	// ********** accessors **********
+
+	/**
+	 * Return the current value.
+	 */
+	public E value() {
+		synchronized (this.mutex) {
+			return this.value;
+		}
+	}
+
+	/**
+	 * Return whether the current value is null.
+	 */
+	public boolean isNull() {
+		synchronized (this.mutex) {
+			return this.value == null;
+		}
+	}
+
+	/**
+	 * Return whether the current value is not null.
+	 */
+	public boolean isNotNull() {
+		synchronized (this.mutex) {
+			return this.value != null;
+		}
+	}
+
+	/**
+	 * Set the value. If the value changes, all waiting
+	 * threads are notified.
+	 */
+	public void setValue(E value) {
+		synchronized (this.mutex) {
+			if (this.value != value) {
+				this.value = value;
+				this.mutex.notifyAll();
+			}
+		}
+	}
+
+	/**
+	 * Set the value to null. If the value changes, all waiting
+	 * threads are notified.
+	 */
+	public void setNull() {
+		synchronized (this.mutex) {
+			this.setValue(null);
+		}
+	}
+
+	/**
+	 * Return the object this object locks on while performing
+	 * its operations.
+	 */
+	public Object mutex() {
+		return this.mutex;
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to the specified value.
+	 */
+	public void waitUntilValueIs(E x) throws InterruptedException {
+		synchronized (this.mutex) {
+			while (this.value != x) {
+				this.mutex.wait();
+			}
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than the specified value.
+	 */
+	public void waitUntilValueIsNot(E x) throws InterruptedException {
+		synchronized (this.mutex) {
+			while (this.value == x) {
+				this.mutex.wait();
+			}
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to null.
+	 */
+	public void waitUntilNull() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIs(null);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than null.
+	 */
+	public void waitUntilNotNull() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIsNot(null);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than the specified value, then change
+	 * it back to the specified value and continue executing.
+	 */
+	public void waitToSetValue(E x) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilValueIsNot(x);
+			this.setValue(x);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * null, then change it back to null and continue executing.
+	 */
+	public void waitToSetNull() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilNotNull();
+			this.setValue(null);
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilValueIs(E x, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			if (timeout == 0L) {
+				this.waitUntilValueIs(x);	// wait indefinitely until notified
+				return true;	// if it ever comes back, the condition was met
+			}
+
+			long stop = System.currentTimeMillis() + timeout;
+			long remaining = timeout;
+			while ((this.value != x) && (remaining > 0L)) {
+				this.mutex.wait(remaining);
+				remaining = stop - System.currentTimeMillis();
+			}
+			return (this.value == x);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to something
+	 * other than the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was removed; return false if a time-out occurred.
+	 */
+	public boolean waitUntilValueIsNot(E x, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			if (timeout == 0L) {
+				this.waitUntilValueIsNot(x);	// wait indefinitely until notified
+				return true;	// if it ever comes back, the condition was met
+			}
+
+			long stop = System.currentTimeMillis() + timeout;
+			long remaining = timeout;
+			while ((this.value == x) && (remaining > 0L)) {
+				this.mutex.wait(remaining);
+				remaining = stop - System.currentTimeMillis();
+			}
+			return (this.value != x);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to null or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilNull(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIs(null, timeout);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes
+	 * to something other than null or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilNotNull(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilValueIsNot(null, timeout);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to
+	 * something other than the specified value, then change
+	 * it back to the specified value and continue executing.
+	 * If the value does not change to something other than the
+	 * specified before the time-out, simply continue executing
+	 * without changing the value.
+	 * The time-out is specified in milliseconds. Return true if the value was
+	 * set to true; return false if a time-out occurred.
+	 */
+	public boolean waitToSetValue(E x, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilValueIsNot(x, timeout);
+			if (success) {
+				this.setValue(x);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the value changes to something
+	 * other than null, then change it back to null and continue executing.
+	 * If the value does not change to something other than null before
+	 * the time-out, simply continue executing without changing the value.
+	 * The time-out is specified in milliseconds. Return true if the value was
+	 * set to false; return false if a time-out occurred.
+	 */
+	public boolean waitToSetNull(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilNotNull(timeout);
+			if (success) {
+				this.setValue(null);
+			}
+			return success;
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If current thread is not interrupted, execute the specified command 
+	 * with the mutex locked. This is useful for initializing the value in another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.interrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public SynchronizedObject<E> clone() {
+		try {
+			synchronized (this.mutex) {
+				@SuppressWarnings("unchecked")
+				SynchronizedObject<E> clone = (SynchronizedObject<E>) super.clone();
+				return clone;
+			}
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if ( ! (obj instanceof SynchronizedObject)) {
+			return false;
+		}
+		Object thisValue = this.value();
+		Object otherValue = ((SynchronizedObject<?>) obj).value();
+		return (thisValue == null) ?
+			(otherValue == null) : thisValue.equals(otherValue);
+	}
+
+	@Override
+	public int hashCode() {
+		Object temp = this.value();
+		return (temp == null) ? 0 : temp.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return String.valueOf(this.value());
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedStack.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedStack.java
new file mode 100644
index 0000000..6455e84
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SynchronizedStack.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+import java.io.Serializable;
+import java.util.EmptyStackException;
+
+/**
+ * Thread-safe implementation of the Stack interface.
+ * This also provides protocol for suspending a thread until the
+ * stack is empty or not empty, with optional time-outs.
+ */
+public class SynchronizedStack<E>
+	implements Stack<E>, Serializable
+{
+	/** Backing stack. */
+	private Stack<E> stack;
+
+	/** Object to synchronize on. */
+	private final Object mutex;
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructors **********
+
+	/**
+	 * Construct a synchronized stack that wraps the
+	 * specified stack and locks on the specified mutex.
+	 */
+	public SynchronizedStack(Stack<E> stack, Object mutex) {
+		super();
+		this.stack = stack;
+		this.mutex = mutex;
+	}
+
+	/**
+	 * Construct a synchronized stack that wraps the
+	 * specified stack and locks on itself.
+	 */
+	public SynchronizedStack(Stack<E> stack) {
+		super();
+		this.stack = stack;
+		this.mutex = this;
+	}
+
+	/**
+	 * Construct a synchronized stack that locks on the specified mutex.
+	 */
+	public SynchronizedStack(Object mutex) {
+		this(new SimpleStack<E>(), mutex);
+	}
+
+	/**
+	 * Construct a synchronized stack that locks on itself.
+	 */
+	public SynchronizedStack() {
+		this(new SimpleStack<E>());
+	}
+
+
+	// ********** Stack implementation **********
+
+	public void push(E o) {
+		synchronized (this.mutex) {
+			this.stack.push(o);
+			this.mutex.notifyAll();
+		}
+	}
+
+	public E pop() {
+		synchronized (this.mutex) {
+			E o = this.stack.pop();
+			this.mutex.notifyAll();
+			return o;
+		}
+	}
+
+	public E peek() {
+		synchronized (this.mutex) {
+			return this.stack.peek();
+		}
+	}
+
+	public boolean isEmpty() {
+		synchronized (this.mutex) {
+			return this.stack.isEmpty();
+		}
+	}
+
+
+	// ********** indefinite waits **********
+
+	/**
+	 * Suspend the current thread until the stack's empty status changes
+	 * to the specified value.
+	 */
+	public void waitUntilEmptyIs(boolean empty) throws InterruptedException {
+		synchronized (this.mutex) {
+			while (this.isEmpty() != empty) {
+				this.mutex.wait();
+			}
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty.
+	 */
+	public void waitUntilEmpty() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs(true);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it.
+	 */
+	public void waitUntilNotEmpty() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmptyIs(false);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty,
+	 * then "push" the specified item on to the top of the stack
+	 * and continue executing.
+	 */
+	public void waitToPush(E o) throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilEmpty();
+			this.push(o);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it,
+	 * then "pop" an item from the top of the stack and return it.
+	 */
+	public Object waitToPop() throws InterruptedException {
+		synchronized (this.mutex) {
+			this.waitUntilNotEmpty();
+			return this.pop();
+		}
+	}
+
+
+	// ********** timed waits **********
+
+	/**
+	 * Suspend the current thread until the stack's empty status changes
+	 * to the specified value or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if the specified
+	 * value was achieved; return false if a time-out occurred.
+	 */
+	public boolean waitUntilEmptyIs(boolean empty, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			if (timeout == 0L) {
+				this.waitUntilEmptyIs(empty);	// wait indefinitely until notified
+				return true;	// if it ever comes back, the condition was met
+			}
+
+			long stop = System.currentTimeMillis() + timeout;
+			long remaining = timeout;
+			while ((this.isEmpty() != empty) && (remaining > 0L)) {
+				this.mutex.wait(remaining);
+				remaining = stop - System.currentTimeMillis();
+			}
+			return (this.isEmpty() == empty);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if
+	 * the stack is empty; return false if a time-out occurred.
+	 */
+	public boolean waitUntilEmpty(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilEmptyIs(true, timeout);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it.
+	 * or the specified time-out occurs.
+	 * The time-out is specified in milliseconds. Return true if
+	 * the stack has something on it; return false if a time-out occurred.
+	 */
+	public boolean waitUntilNotEmpty(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			return this.waitUntilEmptyIs(false, timeout);
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack is empty,
+	 * then "push" the specified item on to the top of the stack
+	 * and continue executing. If the stack is not emptied out
+	 * before the time-out, simply continue executing without
+	 * "pushing" the item.
+	 * The time-out is specified in milliseconds. Return true if the
+	 * item was pushed; return false if a time-out occurred.
+	 */
+	public boolean waitToPush(E o, long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilEmpty(timeout);
+			if (success) {
+				this.push(o);
+			}
+			return success;
+		}
+	}
+
+	/**
+	 * Suspend the current thread until the stack has something on it,
+	 * then "pop" an item from the top of the stack and return it.
+	 * If the stack is empty and nothing is "pushed" on to it before the
+	 * time-out, throw an empty stack exception.
+	 * The time-out is specified in milliseconds.
+	 */
+	public Object waitToPop(long timeout) throws InterruptedException {
+		synchronized (this.mutex) {
+			boolean success = this.waitUntilNotEmpty(timeout);
+			if (success) {
+				return this.pop();
+			}
+			throw new EmptyStackException();
+		}
+	}
+
+
+	// ********** synchronized behavior **********
+
+	/**
+	 * If the current thread is not interrupted, execute the specified command 
+	 * with the mutex locked. This is useful for initializing the stack in another
+	 * thread.
+	 */
+	public void execute(Command command) throws InterruptedException {
+		if (Thread.interrupted()) {
+			throw new InterruptedException();
+		}
+		synchronized (this.mutex) {
+			command.execute();
+		}
+	}
+
+
+	// ********** additional public protocol **********
+
+	/**
+	 * Return the object this object locks on while performing
+	 * its operations.
+	 */
+	public Object getMutex() {
+		return this.mutex;
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public String toString() {
+		synchronized (this.mutex) {
+			return this.stack.toString();
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java
index a7df5c9..e238d4b 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneIterator.java
@@ -45,7 +45,7 @@
 	 * The <code>#remove()</code> method will not be supported,
 	 * unless a subclass overrides the <code>#remove(Object)</code>.
 	 */
-	public CloneIterator(Collection<E> c) {
+	public CloneIterator(Collection<? extends E> c) {
 		this(c, Mutator.ReadOnly.<E>instance());
 	}
 
@@ -54,15 +54,19 @@
 	 * Use the specified mutator to remove objects from the
 	 * original collection.
 	 */
-	@SuppressWarnings("unchecked")
-	public CloneIterator(Collection<E> c, Mutator<E> mutator) {
+	public CloneIterator(Collection<? extends E> c, Mutator<E> mutator) {
 		super();
-		this.nestedIterator = new ArrayIterator<E>((E[]) c.toArray());
+		this.nestedIterator = new ArrayIterator<E>(buildArray(c));
 		this.current = null;
 		this.mutator = mutator;
 		this.removeAllowed = false;
 	}
 
+	@SuppressWarnings("unchecked")
+	private static <T> T[] buildArray(Collection<? extends T> c) {
+		return (T[]) c.toArray();
+	}
+
 
 	// ********** Iterator implementation **********
 
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java
index 82d701b..e360640 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CloneListIterator.java
@@ -9,8 +9,10 @@
  ******************************************************************************/
 package org.eclipse.jpt.utility.internal.iterators;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.ListIterator;
+
 import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.StringTools;
 
@@ -49,7 +51,7 @@
 	 * The modification methods will not be supported,
 	 * unless a subclass overrides them.
 	 */
-	public CloneListIterator(List<E> list) {
+	public CloneListIterator(List<? extends E> list) {
 		this(list, Mutator.ReadOnly.<E>instance());
 	}
 
@@ -57,17 +59,21 @@
 	 * Construct a list iterator on a copy of the specified list.
 	 * Use the specified list mutator to modify the original list.
 	 */
-	@SuppressWarnings("unchecked")
-	public CloneListIterator(List<E> list, Mutator<E> mutator) {
+	public CloneListIterator(List<? extends E> list, Mutator<E> mutator) {
 		super();
 		// build a copy of the list and keep it in synch with original (if the mutator allows changes)
 		// that way the nested list iterator will maintain some of our state
-		this.nestedListIterator = CollectionTools.list((E[]) list.toArray()).listIterator();
+		this.nestedListIterator = CollectionTools.list(buildArray(list)).listIterator();
 		this.mutator = mutator;
 		this.cursor = 0;
 		this.state = UNKNOWN;
 	}
 
+	@SuppressWarnings("unchecked")
+	private static <T> T[] buildArray(Collection<? extends T> c) {
+		return (T[]) c.toArray();
+	}
+
 
 	// ********** ListIterator implementation **********
 
@@ -164,6 +170,9 @@
 		this.mutator.set(index, o);
 	}
 
+
+	// ********** overrides **********
+
 	@Override
 	public String toString() {
 		return StringTools.buildToStringFor(this);
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java
index 40ae0cb..083f535 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/CompositeIterator.java
@@ -27,6 +27,8 @@
 	private Iterator<? extends E> lastIteratorToReturnNext;
 
 
+	// ********** constructors **********
+
 	/**
 	 * Construct an iterator with the specified collection of iterators.
 	 */
@@ -67,6 +69,9 @@
 		this(new ArrayIterator<Iterator<? extends E>>(iterators));
 	}
 
+
+	// ********** Iterator implementation **********
+
 	public boolean hasNext() {
 		try {
 			this.loadCurrentIterator();
@@ -110,6 +115,9 @@
 		}
 	}
 
+
+	// ********** overrides **********
+
 	@Override
 	public String toString() {
 		return StringTools.buildToStringFor(this, this.iterators);
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java
index d1b989a..1e7721a 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyEnumeration.java
@@ -22,7 +22,7 @@
 
 	// singleton
 	@SuppressWarnings("unchecked")
-	private static EmptyEnumeration INSTANCE = new EmptyEnumeration();
+	private static final EmptyEnumeration INSTANCE = new EmptyEnumeration();
 
 	/**
 	 * Return the singleton.
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java
index b560d45..cb85a24 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyIterator.java
@@ -22,7 +22,7 @@
 
 	// singleton
 	@SuppressWarnings("unchecked")
-	private static EmptyIterator INSTANCE = new EmptyIterator();
+	private static final EmptyIterator INSTANCE = new EmptyIterator();
 
 	/**
 	 * Return the singleton.
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java
index 0863b24..ba93e81 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/EmptyListIterator.java
@@ -11,6 +11,7 @@
 
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
+
 import org.eclipse.jpt.utility.internal.StringTools;
 
 /**
@@ -22,7 +23,7 @@
 
 	// singleton
 	@SuppressWarnings("unchecked")
-	private static EmptyListIterator INSTANCE = new EmptyListIterator();
+	private static final EmptyListIterator INSTANCE = new EmptyListIterator();
 
 	/**
 	 * Return the singleton.
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java
index eb0c970..f8491fc 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/iterators/FilteringIterator.java
@@ -59,8 +59,7 @@
 	 * Construct an iterator with the specified nested
 	 * iterator and filter.
 	 */
-	@SuppressWarnings("unchecked")
-	public FilteringIterator(Iterator<?> nestedIterator, Filter filter) {
+	public FilteringIterator(Iterator<?> nestedIterator, @SuppressWarnings("unchecked") Filter filter) {
 		super();
 		this.nestedIterator = nestedIterator;
 		this.filter = filter;
@@ -93,14 +92,13 @@
 	 * Load next with the next valid entry from the nested
 	 * iterator. If there are none, next is set to <code>END</code>.
 	 */
-	@SuppressWarnings("unchecked")
 	private void loadNext() {
 		this.done = true;
 		while (this.nestedIterator.hasNext() && (this.done)) {
 			Object o = this.nestedIterator.next();
 			if (this.accept(o)) {
 				// assume that if the object was accepted it is of type E
-				this.next = (E) o;
+				this.next = this.downcast(o);
 				this.done = false;
 			} else {
 				this.next = null;
@@ -109,6 +107,11 @@
 		}
 	}
 
+	@SuppressWarnings("unchecked")
+	private E downcast(Object o) {
+		return (E) o;
+	}
+
 	/**
 	 * Return whether the <code>FilteringIterator</code>
 	 * should return the specified next element from a call to the
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AWTChangeEventDispatcher.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AWTChangeEventDispatcher.java
new file mode 100644
index 0000000..b3e0b20
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AWTChangeEventDispatcher.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import java.awt.EventQueue;
+import java.io.Serializable;
+
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * AWT-aware implementation of ChangeEventDispatcher interface:
+ * If we are executing on the AWT event-dispatch thread,
+ * simply forward the change notification directly to the listener.
+ * If we are executing on some other thread, queue up the
+ * notification on the AWT event queue so it can be executed
+ * on the event-dispatch thread (after the pending events have
+ * been dispatched).
+ */
+public class AWTChangeEventDispatcher
+	implements ChangeEventDispatcher, Serializable
+{
+	// singleton
+	private static ChangeEventDispatcher INSTANCE;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Return the singleton.
+	 */
+	public synchronized static ChangeEventDispatcher instance() {
+		if (INSTANCE == null) {
+			INSTANCE = new AWTChangeEventDispatcher();
+		}
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private AWTChangeEventDispatcher() {
+		super();
+	}
+
+	public void stateChanged(final StateChangeListener listener, final StateChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.stateChanged(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.stateChanged(event);
+					}
+					@Override
+					public String toString() {
+						return "stateChanged";
+					}
+				}
+			);
+		}
+	}
+
+	public void propertyChanged(final PropertyChangeListener listener, final PropertyChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.propertyChanged(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.propertyChanged(event);
+					}
+					@Override
+					public String toString() {
+						return "propertyChanged";
+					}
+				}
+			);
+		}
+	}
+
+	public void itemsAdded(final CollectionChangeListener listener, final CollectionChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.itemsAdded(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.itemsAdded(event);
+					}
+					@Override
+					public String toString() {
+						return "itemsAdded (Collection)";
+					}
+				}
+			);
+		}
+	}
+
+	public void itemsRemoved(final CollectionChangeListener listener, final CollectionChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.itemsRemoved(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.itemsRemoved(event);
+					}
+					@Override
+					public String toString() {
+						return "itemsRemoved (Collection)";
+					}
+				}
+			);
+		}
+	}
+
+	public void collectionCleared(final CollectionChangeListener listener, final CollectionChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.collectionCleared(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.collectionCleared(event);
+					}
+					@Override
+					public String toString() {
+						return "collectionCleared";
+					}
+				}
+			);
+		}
+	}
+
+	public void collectionChanged(final CollectionChangeListener listener, final CollectionChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.collectionChanged(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.collectionChanged(event);
+					}
+					@Override
+					public String toString() {
+						return "collectionChanged";
+					}
+				}
+			);
+		}
+	}
+
+	public void itemsAdded(final ListChangeListener listener, final ListChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.itemsAdded(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.itemsAdded(event);
+					}
+					@Override
+					public String toString() {
+						return "itemsAdded (List)";
+					}
+				}
+			);
+		}
+	}
+
+	public void itemsRemoved(final ListChangeListener listener, final ListChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.itemsRemoved(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.itemsRemoved(event);
+					}
+					@Override
+					public String toString() {
+						return "itemsRemoved (List)";
+					}
+				}
+			);
+		}
+	}
+
+	public void itemsReplaced(final ListChangeListener listener, final ListChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.itemsReplaced(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.itemsReplaced(event);
+					}
+					@Override
+					public String toString() {
+						return "itemsReplaced (List)";
+					}
+				}
+			);
+		}
+	}
+
+	public void itemsMoved(final ListChangeListener listener, final ListChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.itemsMoved(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.itemsMoved(event);
+					}
+					@Override
+					public String toString() {
+						return "itemsMoved (List)";
+					}
+				}
+			);
+		}
+	}
+
+	public void listCleared(final ListChangeListener listener, final ListChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.listCleared(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.listCleared(event);
+					}
+					@Override
+					public String toString() {
+						return "listCleared";
+					}
+				}
+			);
+		}
+	}
+
+	public void listChanged(final ListChangeListener listener, final ListChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.listChanged(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.listChanged(event);
+					}
+					@Override
+					public String toString() {
+						return "listChanged";
+					}
+				}
+			);
+		}
+	}
+
+	public void nodeAdded(final TreeChangeListener listener, final TreeChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.nodeAdded(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.nodeAdded(event);
+					}
+					@Override
+					public String toString() {
+						return "nodeAdded";
+					}
+				}
+			);
+		}
+	}
+
+	public void nodeRemoved(final TreeChangeListener listener, final TreeChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.nodeRemoved(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.nodeRemoved(event);
+					}
+					@Override
+					public String toString() {
+						return "nodeRemoved";
+					}
+				}
+			);
+		}
+	}
+
+	public void treeCleared(final TreeChangeListener listener, final TreeChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.treeCleared(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.treeCleared(event);
+					}
+					@Override
+					public String toString() {
+						return "treeCleared";
+					}
+				}
+			);
+		}
+	}
+
+	public void treeChanged(final TreeChangeListener listener, final TreeChangeEvent event) {
+		if (EventQueue.isDispatchThread()) {
+			listener.treeChanged(event);
+		} else {
+			this.invoke(
+				new Runnable() {
+					public void run() {
+						listener.treeChanged(event);
+					}
+					@Override
+					public String toString() {
+						return "treeChanged";
+					}
+				}
+			);
+		}
+	}
+
+	/**
+	 * EventQueue.invokeLater(Runnable) seems to work OK;
+	 * but using #invokeAndWait() can somtimes make things
+	 * more predictable when debugging.
+	 */
+	private void invoke(Runnable r) {
+		EventQueue.invokeLater(r);
+//		try {
+//			EventQueue.invokeAndWait(r);
+//		} catch (InterruptedException ex) {
+//			throw new RuntimeException(ex);
+//		} catch (java.lang.reflect.InvocationTargetException ex) {
+//			throw new RuntimeException(ex);
+//		}
+	}
+
+	/**
+	 * Serializable singleton support
+	 */
+	private Object readResolve() {
+		return instance();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java
new file mode 100644
index 0000000..6a3af61
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/AbstractModel.java
@@ -0,0 +1,776 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.HashBag;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Convenience implementation of Model protocol.
+ */
+public abstract class AbstractModel implements Model, Serializable {
+	/**
+	 * Delegate state/property/collection/list/tree change support to this
+	 * helper object. The change support object is "lazy-initialized".
+	 */
+	private ChangeSupport changeSupport;
+
+
+	// ********** constructors/initialization **********
+
+	/**
+	 * Default constructor.
+	 * This will call #initialize() on the newly-created instance.
+	 */
+	protected AbstractModel() {
+		super();
+		this.initialize();
+	}
+
+	protected void initialize() {
+		// do nothing by default
+	}
+
+	/**
+	 * This accessor will build the change support when required.
+	 */
+	private synchronized ChangeSupport changeSupport() {
+		if (this.changeSupport == null) {
+			this.changeSupport = this.buildChangeSupport();
+		}
+		return this.changeSupport;
+	}
+
+	/**
+	 * Allow subclasses to tweak the change support used.
+	 */
+	protected ChangeSupport buildChangeSupport() {
+		return new ChangeSupport(this);
+	}
+
+
+	// ********** state change support **********
+
+	public synchronized void addStateChangeListener(StateChangeListener listener) {
+		this.changeSupport().addStateChangeListener(listener);
+	}
+
+	public synchronized void removeStateChangeListener(StateChangeListener listener) {
+		this.changeSupport().removeStateChangeListener(listener);
+	}
+
+	protected final void fireStateChanged() {
+		this.changeSupport().fireStateChanged();
+	}
+
+	protected final void fireStateChanged(StateChangeEvent event) {
+		this.changeSupport().fireStateChanged(event);
+	}
+
+
+	// ********** property change support **********
+
+	public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+		this.changeSupport().addPropertyChangeListener(listener);
+	}
+
+	public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		this.changeSupport().addPropertyChangeListener(propertyName, listener);
+	}
+
+	public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+		this.changeSupport().removePropertyChangeListener(listener);
+	}
+
+	public synchronized void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		this.changeSupport().removePropertyChangeListener(propertyName, listener);
+	}
+
+	protected final void firePropertyChanged(String propertyName, Object oldValue, Object newValue) {
+		this.changeSupport().firePropertyChanged(propertyName, oldValue, newValue);
+	}
+
+	protected final void firePropertyChanged(String propertyName, int oldValue, int newValue) {
+		this.changeSupport().firePropertyChanged(propertyName, oldValue, newValue);
+	}
+
+	protected final void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) {
+		this.changeSupport().firePropertyChanged(propertyName, oldValue, newValue);
+	}
+
+	protected final void firePropertyChanged(String propertyName, Object newValue) {
+		this.changeSupport().firePropertyChanged(propertyName, null, newValue);
+	}
+
+	protected final void firePropertyChanged(PropertyChangeEvent event) {
+		this.changeSupport().firePropertyChanged(event);
+	}
+
+
+	// ********** collection change support **********
+
+	public synchronized void addCollectionChangeListener(CollectionChangeListener listener) {
+		this.changeSupport().addCollectionChangeListener(listener);
+	}
+
+	public synchronized void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		this.changeSupport().addCollectionChangeListener(collectionName, listener);
+	}
+
+	public synchronized void removeCollectionChangeListener(CollectionChangeListener listener) {
+		this.changeSupport().removeCollectionChangeListener(listener);
+	}
+
+	public synchronized void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		this.changeSupport().removeCollectionChangeListener(collectionName, listener);
+	}
+
+	protected final void fireItemAdded(String collectionName, Object addedItem) {
+		this.changeSupport().fireItemAdded(collectionName, addedItem);
+	}
+
+	protected final void fireItemsAdded(String collectionName, Collection<?> addedItems) {
+		this.changeSupport().fireItemsAdded(collectionName, addedItems);
+	}
+
+	protected final void fireItemsAdded(CollectionChangeEvent event) {
+		this.changeSupport().fireItemsAdded(event);
+	}
+
+	protected final void fireItemRemoved(String collectionName, Object removedItem) {
+		this.changeSupport().fireItemRemoved(collectionName, removedItem);
+	}
+
+	protected final void fireItemsRemoved(String collectionName, Collection<?> removedItems) {
+		this.changeSupport().fireItemsRemoved(collectionName, removedItems);
+	}
+
+	protected final void fireItemsRemoved(CollectionChangeEvent event) {
+		this.changeSupport().fireItemsRemoved(event);
+	}
+
+	protected final void fireCollectionCleared(String collectionName) {
+		this.changeSupport().fireCollectionCleared(collectionName);
+	}
+
+	protected final void fireCollectionCleared(CollectionChangeEvent event) {
+		this.changeSupport().fireCollectionCleared(event);
+	}
+
+	protected final void fireCollectionChanged(String collectionName) {
+		this.changeSupport().fireCollectionChanged(collectionName);
+	}
+
+	protected final void fireCollectionChanged(CollectionChangeEvent event) {
+		this.changeSupport().fireCollectionChanged(event);
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified item to the specified bound collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether the collection changed.
+	 */
+	protected <E> boolean addItemToCollection(E item, Collection<E> collection, String collectionName) {
+		if (collection.add(item)) {
+			this.fireItemAdded(collectionName, item);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified items to the specified bound collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether collection changed.
+	 */
+	protected <E> boolean addItemsToCollection(Iterable<? extends E> items, Collection<E> collection, String collectionName) {
+		return this.addItemsToCollection(items.iterator(), collection, collectionName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified items to the specified bound collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether collection changed.
+	 */
+	protected <E> boolean addItemsToCollection(Iterator<? extends E> items, Collection<E> collection, String collectionName) {
+		Collection<E> addedItems = null;
+		while (items.hasNext()) {
+			E item = items.next();
+			if (collection.add(item)) {
+				if (addedItems == null) {
+					addedItems = new ArrayList<E>();
+				}
+				addedItems.add(item);
+			}
+		}
+		if (addedItems != null) {
+			this.fireItemsAdded(collectionName, addedItems);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified item from the specified bound collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether the collection changed.
+	 * @see java.util.Collection#remove(Object)
+	 */
+	protected boolean removeItemFromCollection(Object item, Collection<?> collection, String collectionName) {
+		if (collection.remove(item)) {
+			this.fireItemRemoved(collectionName, item);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified items from the specified bound collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether the collection changed.
+	 * @see java.util.Collection#remove(Object)
+	 */
+	protected boolean removeItemsFromCollection(Iterable<?> items, Collection<?> collection, String collectionName) {
+		return this.removeItemsFromCollection(items.iterator(), collection, collectionName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified items from the specified bound collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether the collection changed.
+	 * @see java.util.Collection#remove(Object)
+	 */
+	protected boolean removeItemsFromCollection(Iterator<?> items, Collection<?> collection, String collectionName) {
+		Collection<?> items2 = CollectionTools.collection(items);
+		items2.retainAll(collection);
+		boolean changed = collection.removeAll(items2);
+
+		if ( ! items2.isEmpty()) {
+			this.fireItemsRemoved(collectionName, items2);
+		}
+		return changed;
+	}
+
+	/**
+	 * Convenience method.
+	 * Clear the entire collection
+	 * and fire the appropriate event if necessary.
+	 * Return whether the list changed.
+	 */
+	protected boolean clearCollection(Collection<?> collection, String collectionName) {
+		if (collection.isEmpty()) {
+			return false;
+		}
+		collection.clear();
+		this.fireCollectionCleared(collectionName);
+		return true;
+	}
+
+	/**
+	 * Convenience method.
+	 * Synchronize the collection with the specified new collection,
+	 * making a minimum number of removes and adds.
+	 * Return whether the collection changed.
+	 */
+	protected <E> boolean synchronizeCollection(Collection<E> newCollection, Collection<E> collection, String collectionName) {
+		if (newCollection.isEmpty()) {
+			return this.clearCollection(collection, collectionName);
+		}
+
+		if (collection.isEmpty()) {
+			return this.addItemsToCollection(newCollection, collection, collectionName);
+		}
+
+		boolean changed = false;
+		Collection<E> removeItems = new HashBag<E>(collection);
+		removeItems.removeAll(newCollection);
+		changed |= this.removeItemsFromCollection(removeItems, collection, collectionName);
+
+		Collection<E> addItems = new HashBag<E>(newCollection);
+		addItems.removeAll(collection);
+		changed |= this.addItemsToCollection(addItems, collection, collectionName);
+
+		return changed;
+	}
+
+	/**
+	 * Convenience method.
+	 * Synchronize the collection with the specified new collection,
+	 * making a minimum number of removes and adds.
+	 * Return whether the collection changed.
+	 */
+	protected <E> boolean synchronizeCollection(Iterator<E> newItems, Collection<E> collection, String collectionName) {
+		return this.synchronizeCollection(CollectionTools.collection(newItems), collection, collectionName);
+	}
+
+
+	// ********** list change support **********
+
+	public synchronized void addListChangeListener(ListChangeListener listener) {
+		this.changeSupport().addListChangeListener(listener);
+	}
+
+	public synchronized void addListChangeListener(String listName, ListChangeListener listener) {
+		this.changeSupport().addListChangeListener(listName, listener);
+	}
+
+	public synchronized void removeListChangeListener(ListChangeListener listener) {
+		this.changeSupport().removeListChangeListener(listener);
+	}
+
+	public synchronized void removeListChangeListener(String listName, ListChangeListener listener) {
+		this.changeSupport().removeListChangeListener(listName, listener);
+	}
+
+	protected final void fireItemAdded(String listName, int index, Object addedItem) {
+		this.changeSupport().fireItemAdded(listName, index, addedItem);
+	}
+
+	protected final void fireItemsAdded(String listName, int index, List<?> addedItems) {
+		this.changeSupport().fireItemsAdded(listName, index, addedItems);
+	}
+
+	protected final void fireItemsAdded(ListChangeEvent event) {
+		this.changeSupport().fireItemsAdded(event);
+	}
+
+	protected final void fireItemRemoved(String listName, int index, Object removedItem) {
+		this.changeSupport().fireItemRemoved(listName, index, removedItem);
+	}
+
+	protected final void fireItemsRemoved(String listName, int index, List<?> removedItems) {
+		this.changeSupport().fireItemsRemoved(listName, index, removedItems);
+	}
+
+	protected final void fireItemsRemoved(ListChangeEvent event) {
+		this.changeSupport().fireItemsRemoved(event);
+	}
+
+	protected final void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) {
+		this.changeSupport().fireItemReplaced(listName, index, newItem, replacedItem);
+	}
+
+	protected final <E> void fireItemsReplaced(String listName, int index, List<? extends E> newItems, List<E> replacedItems) {
+		this.changeSupport().fireItemsReplaced(listName, index, newItems, replacedItems);
+	}
+
+	protected final void fireItemsReplaced(ListChangeEvent event) {
+		this.changeSupport().fireItemsReplaced(event);
+	}
+
+	protected final void fireItemMoved(String listName, int targetIndex, int sourceIndex) {
+		this.changeSupport().fireItemMoved(listName, targetIndex, sourceIndex);
+	}
+
+	protected final <E> void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) {
+		this.changeSupport().fireItemsMoved(listName, targetIndex, sourceIndex, length);
+	}
+
+	protected final void fireItemsMoved(ListChangeEvent event) {
+		this.changeSupport().fireItemsMoved(event);
+	}
+
+	protected final void fireListCleared(String listName) {
+		this.changeSupport().fireListCleared(listName);
+	}
+
+	protected final void fireListCleared(ListChangeEvent event) {
+		this.changeSupport().fireListCleared(event);
+	}
+
+	protected final void fireListChanged(String listName) {
+		this.changeSupport().fireListChanged(listName);
+	}
+
+	protected final void fireListChanged(ListChangeEvent event) {
+		this.changeSupport().fireListChanged(event);
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified item to the specified bound list
+	 * and fire the appropriate event if necessary.
+	 */
+	protected <E> void addItemToList(int index, E item, List<E> list, String listName) {
+		list.add(index, item);
+		this.fireItemAdded(listName, index, item);
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified item to the end of the specified bound list
+	 * and fire the appropriate event if necessary.
+	 */
+	protected <E> void addItemToList(E item, List<E> list, String listName) {
+		this.addItemToList(list.size(), item, list, listName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified items to the specified bound list
+	 * and fire the appropriate event if necessary.
+	 */
+	protected <E> void addItemsToList(int index, List<? extends E> items, List<E> list, String listName) {
+		list.addAll(index, items);
+		this.fireItemsAdded(listName, index, items);
+	}
+
+	/**
+	 * Convenience method.
+	 * Add the specified items to the end of to the specified bound list
+	 * and fire the appropriate event if necessary.
+	 */
+	protected <E> void addItemsToList(List<? extends E> items, List<E> list, String listName) {
+		this.addItemsToList(list.size(), items, list, listName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified item from the specified bound list
+	 * and fire the appropriate event if necessary.
+	 * Return the removed item.
+	 */
+	protected Object removeItemFromList(int index, List<?> list, String listName) {
+		Object item = list.remove(index);
+		this.fireItemRemoved(listName, index, item);
+		return item;
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified item from the specified bound list
+	 * and fire the appropriate event if necessary.
+	 * Return the removed item.
+	 */
+	protected Object removeItemFromList(Object item, List<?> list, String listName) {
+		return this.removeItemFromList(list.indexOf(item), list, listName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Remove the specified items from the specified bound list
+	 * and fire the appropriate event if necessary.
+	 * Return the removed items.
+	 */
+	protected <E> List<E> removeItemsFromList(int index, int length, List<E> list, String listName) {
+		List<E> subList = list.subList(index, index + length);
+		List<E> removedItems = new ArrayList<E>(subList);
+		subList.clear();
+		this.fireItemsRemoved(listName, index, removedItems);
+		return removedItems;
+	}
+
+	/**
+	 * Convenience method.
+	 * Set the specified item in the specified bound list
+	 * and fire the appropriate event if necessary.
+	 * Return the replaced item.
+	 */
+	protected <E> E setItemInList(int index, E item, List<E> list, String listName) {
+		E replacedItem = list.set(index, item);
+		this.fireItemReplaced(listName, index, item, replacedItem);
+		return replacedItem;
+	}
+
+	/**
+	 * Convenience method.
+	 * Replace the specified item in the specified bound list
+	 * and fire the appropriate event if necessary.
+	 * Return the replaced item.
+	 */
+	protected <E> E replaceItemInList(E oldItem, E newItem, List<E> list, String listName) {
+		return this.setItemInList(list.indexOf(oldItem), newItem, list, listName);
+	}
+
+	/**
+	 * Convenience method.
+	 * Set the specified items in the specified bound list
+	 * and fire the appropriate event if necessary.
+	 * Return the replaced items.
+	 */
+	protected <E> List<E> setItemsInList(int index, List<? extends E> items, List<E> list, String listName) {
+		List<E> subList = list.subList(index, index + items.size());
+		List<E> replacedItems = new ArrayList<E>(subList);
+		for (int i = 0; i < items.size(); i++) {
+			subList.set(i, items.get(i));
+		}
+		this.fireItemsReplaced(listName, index, items, replacedItems);
+		return replacedItems;
+	}
+
+	/**
+	 * Convenience method.
+	 * Move items in the specified list from the specified source index to the
+	 * specified target index for the specified length.
+	 */
+	protected <E> void moveItemsInList(int targetIndex, int sourceIndex, int length, List<E> list, String listName) {
+		CollectionTools.move(list, targetIndex, sourceIndex, length);
+		this.fireItemsMoved(listName, targetIndex, sourceIndex, length);
+	}
+
+	/**
+	 * Convenience method.
+	 * Move an item in the specified list from the specified source index to the
+	 * specified target index.
+	 */
+	protected <E> void moveItemInList(int targetIndex, int sourceIndex, List<E> list, String listName) {
+		CollectionTools.move(list, targetIndex, sourceIndex);
+		this.fireItemMoved(listName, targetIndex, sourceIndex);
+	}
+
+	/**
+	 * Convenience method.
+	 * Clear the entire list
+	 * and fire the appropriate event if necessary.
+	 * Return whether the list changed.
+	 */
+	protected boolean clearList(List<?> list, String listName) {
+		if (list.isEmpty()) {
+			return false;
+		}
+		list.clear();
+		this.fireListCleared(listName);
+		return true;
+	}
+
+
+	// ********** tree change support **********
+
+	public synchronized void addTreeChangeListener(TreeChangeListener listener) {
+		this.changeSupport().addTreeChangeListener(listener);
+	}
+
+	public synchronized void addTreeChangeListener(String treeName, TreeChangeListener listener) {
+		this.changeSupport().addTreeChangeListener(treeName, listener);
+	}
+
+	public synchronized void removeTreeChangeListener(TreeChangeListener listener) {
+		this.changeSupport().removeTreeChangeListener(listener);
+	}
+
+	public synchronized void removeTreeChangeListener(String treeName, TreeChangeListener listener) {
+		this.changeSupport().removeTreeChangeListener(treeName, listener);
+	}
+
+	protected final void fireNodeAdded(String treeName, Object[] path) {
+		this.changeSupport().fireNodeAdded(treeName, path);
+	}
+
+	protected final void fireNodeAdded(TreeChangeEvent event) {
+		this.changeSupport().fireNodeAdded(event);
+	}
+
+	protected final void fireNodeRemoved(String treeName, Object[] path) {
+		this.changeSupport().fireNodeRemoved(treeName, path);
+	}
+
+	protected final void fireNodeRemoved(TreeChangeEvent event) {
+		this.changeSupport().fireNodeRemoved(event);
+	}
+
+	protected final void fireTreeCleared(String treeName) {
+		this.changeSupport().fireTreeCleared(treeName);
+	}
+
+	protected final void fireTreeCleared(TreeChangeEvent event) {
+		this.changeSupport().fireTreeCleared(event);
+	}
+
+	protected final void fireTreeChanged(String treeName) {
+		this.changeSupport().fireTreeChanged(treeName);
+	}
+
+	protected final void fireTreeChanged(String treeName, Object[] path) {
+		this.changeSupport().fireTreeChanged(treeName, path);
+	}
+
+	protected final void fireTreeChanged(TreeChangeEvent event) {
+		this.changeSupport().fireTreeChanged(event);
+	}
+
+
+	// ********** queries **********
+
+	/**
+	 * Return whether there are any state change listeners.
+	 */
+	public boolean hasAnyStateChangeListeners() {
+		return this.changeSupport().hasAnyStateChangeListeners();
+	}
+
+	/**
+	 * Return whether there are no state change listeners.
+	 */
+	public boolean hasNoStateChangeListeners() {
+		return ! this.hasAnyStateChangeListeners();
+	}
+
+	/**
+	 * Return whether there are any property change listeners for a specific property.
+	 */
+	public boolean hasAnyPropertyChangeListeners(String propertyName) {
+		return this.changeSupport().hasAnyPropertyChangeListeners(propertyName);
+	}
+
+	/**
+	 * Return whether there are any property change listeners for a specific property.
+	 */
+	public boolean hasNoPropertyChangeListeners(String propertyName) {
+		return ! this.hasAnyPropertyChangeListeners(propertyName);
+	}
+
+	/**
+	 * Return whether there are any collection change listeners for a specific collection.
+	 */
+	public boolean hasAnyCollectionChangeListeners(String collectionName) {
+		return this.changeSupport().hasAnyCollectionChangeListeners(collectionName);
+	}
+
+	/**
+	 * Return whether there are any collection change listeners for a specific collection.
+	 */
+	public boolean hasNoCollectionChangeListeners(String collectionName) {
+		return ! this.hasAnyCollectionChangeListeners(collectionName);
+	}
+
+	/**
+	 * Return whether there are any list change listeners for a specific list.
+	 */
+	public boolean hasAnyListChangeListeners(String listName) {
+		return this.changeSupport().hasAnyListChangeListeners(listName);
+	}
+
+	/**
+	 * Return whether there are any list change listeners for a specific list.
+	 */
+	public boolean hasNoListChangeListeners(String listName) {
+		return ! this.hasAnyListChangeListeners(listName);
+	}
+
+	/**
+	 * Return whether there are any tree change listeners for a specific tree.
+	 */
+	public boolean hasAnyTreeChangeListeners(String treeName) {
+		return this.changeSupport().hasAnyTreeChangeListeners(treeName);
+	}
+
+	/**
+	 * Return whether there are any tree change listeners for a specific tree.
+	 */
+	public boolean hasNoTreeChangeListeners(String treeName) {
+		return ! this.hasAnyTreeChangeListeners(treeName);
+	}
+
+
+	// ********** convenience methods **********
+
+	/**
+	 * Return whether the values are equal, with the appropriate null checks.
+	 * Convenience method for checking whether an attribute value has changed.
+	 * 
+	 * DO NOT use this to determine whether to fire a change notification,
+	 * ChangeSupport already does that.
+	 */
+	protected final boolean valuesAreEqual(Object value1, Object value2) {
+		return this.changeSupport().valuesAreEqual(value1, value2);
+	}
+	protected final boolean attributeValueHasNotChanged(Object oldValue, Object newValue) {
+		return this.valuesAreEqual(oldValue, newValue);
+	}
+
+
+	/**
+	 * Return whether the values are different, with the appropriate null checks.
+	 * Convenience method for checking whether an attribute value has changed.
+	 * 
+	 * DO NOT use this to determine whether to fire a change notification,
+	 * ChangeSupport already does that.
+	 * 
+	 * For example, after firing the change notification, you can use this method
+	 * to decide if some other, related, piece of state needs to be synchronized
+	 * with the state that just changed.
+	 */
+	protected final boolean valuesAreDifferent(Object value1, Object value2) {
+		return this.changeSupport().valuesAreDifferent(value1, value2);
+	}
+	protected final boolean attributeValueHasChanged(Object oldValue, Object newValue) {
+		return this.valuesAreDifferent(oldValue, newValue);
+	}
+
+
+	// ********** Object overrides **********
+
+	/**
+	 * Although cloning models is usually not a Good Idea,
+	 * we should at least support it properly.
+	 */
+	@Override
+	protected AbstractModel clone() throws CloneNotSupportedException {
+		AbstractModel clone = (AbstractModel) super.clone();
+		clone.postClone();
+		return clone;
+	}
+
+	/**
+	 * Perform any post-clone processing necessary to
+	 * successfully disconnect the clone from the original.
+	 * When this method is called on the clone, the clone
+	 * is a "shallow" copy of the original (i.e. the clone
+	 * shares all its instance variables with the original).
+	 */
+	protected void postClone() {
+		// clear out change support - models do not share listeners
+		this.changeSupport = null;
+	// when you override this method, don't forget to include:
+	//	super.postClone();
+	}
+
+	@Override
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		StringTools.buildSimpleToStringOn(this, sb);
+		sb.append(" (");
+		this.toString(sb);
+		sb.append(')');
+		return sb.toString();
+	}
+
+	/**
+	 * make this public so one model can call a nested model's
+	 * #toString(StringBuffer)
+	 */
+	public void toString(StringBuffer sb) {
+		// subclasses should override this to do something a bit more helpful
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeEventDispatcher.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeEventDispatcher.java
new file mode 100644
index 0000000..68727bf
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeEventDispatcher.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Add yet another level of indirection to change support to allow
+ * clients to change how and when listener notification occurs.
+ * The primary use would be to dispatch the notification to the
+ * AWT event queue, so the UI will be updated in a single thread.
+ */
+public interface ChangeEventDispatcher {
+
+	/**
+	 * Notify the specified listener that the source's state changed,
+	 * as described in the specified event.
+	 */
+	void stateChanged(StateChangeListener listener, StateChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound property changed,
+	 * as described in the specified event.
+	 */
+	void propertyChanged(PropertyChangeListener listener, PropertyChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound collection changed,
+	 * as described in the specified event.
+	 */
+	void itemsAdded(CollectionChangeListener listener, CollectionChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound collection changed,
+	 * as described in the specified event.
+	 */
+	void itemsRemoved(CollectionChangeListener listener, CollectionChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound collection changed,
+	 * as described in the specified event.
+	 */
+	void collectionCleared(CollectionChangeListener listener, CollectionChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound collection changed,
+	 * as described in the specified event.
+	 */
+	void collectionChanged(CollectionChangeListener listener, CollectionChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound list changed,
+	 * as described in the specified event.
+	 */
+	void itemsAdded(ListChangeListener listener, ListChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound list changed,
+	 * as described in the specified event.
+	 */
+	void itemsRemoved(ListChangeListener listener, ListChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound list changed,
+	 * as described in the specified event.
+	 */
+	void itemsReplaced(ListChangeListener listener, ListChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound list changed,
+	 * as described in the specified event.
+	 */
+	void itemsMoved(ListChangeListener listener, ListChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound list changed,
+	 * as described in the specified event.
+	 */
+	void listCleared(ListChangeListener listener, ListChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound list changed,
+	 * as described in the specified event.
+	 */
+	void listChanged(ListChangeListener listener, ListChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound tree changed,
+	 * as described in the specified event.
+	 */
+	void nodeAdded(TreeChangeListener listener, TreeChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound tree changed,
+	 * as described in the specified event.
+	 */
+	void nodeRemoved(TreeChangeListener listener, TreeChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound tree changed,
+	 * as described in the specified event.
+	 */
+	void treeCleared(TreeChangeListener listener, TreeChangeEvent event);
+
+	/**
+	 * Notify the specified listener that a bound tree changed,
+	 * as described in the specified event.
+	 */
+	void treeChanged(TreeChangeListener listener, TreeChangeEvent event);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java
new file mode 100644
index 0000000..fbef424
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/ChangeSupport.java
@@ -0,0 +1,2366 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.ChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Support object that can be used by implementors of the Model interface.
+ * It provides for state, property, collection, list, and tree change notifications to
+ * listeners.
+ * 
+ * NB: There is lots of copy-n-paste code in this class. Nearly all of this duplication
+ * is an effort to prevent the unnecessary creation of new objects (typically event
+ * objects). Since many events are fired when there are no listeners, we postpone
+ * the creation of event objects until we know we have interested listeners.
+ * Most methods have the "non-duplicated" version of the method body commented
+ * out at the top of the current method body.
+ * The hope was that this class would prove to be fairly static and the duplicated
+ * code would not prove onerous; but that has not proven to be
+ * the case, as we have added support for "state" changes, "dirty" notification,
+ * and custom "notifiers", with more to come, I'm sure....  ~bjv
+ * 
+ * NB2: This class will check to see if, during the firing of events, a listener
+ * on the original list of listeners has been removed from the mast list of
+ * listeners *before* it is notified. If the listener has been removed
+ * "concurrently" it will *not* be notified. (See the code that uses the
+ * 'stillListening' local boolean flag.)
+ * 
+ * NB3: This class is serializable, but it will only write out listeners that
+ * are also serializable while silently leaving behind listeners that are not.
+ */
+public class ChangeSupport
+	implements Serializable
+{
+
+	/** The object to be provided as the "source" for any generated events. */
+	protected final Object source;
+
+	/** Maps a listener class to a collection of "generic" listeners for that class. */
+	transient private GenericListenerList[] genericListeners = EMPTY_GENERIC_LISTENERS;
+		private static final GenericListenerList[] EMPTY_GENERIC_LISTENERS = new GenericListenerList[0];
+
+	/** Maps aspect names to child change support objects. */
+	private AspectChild[] aspectChildren = EMPTY_ASPECT_CHILDREN;
+		private static final AspectChild[] EMPTY_ASPECT_CHILDREN = new AspectChild[0];
+
+	private static final long serialVersionUID = 1L;
+
+
+	// ********** constructor **********
+
+	/**
+	 * Construct support for the specified source of change events.
+	 * The source cannot be null.
+	 */
+	public ChangeSupport(Object source) {
+		super();
+		if (source == null) {
+			throw new NullPointerException();
+		}
+		this.source = source;
+	}
+
+
+	// ********** internal behavior **********
+
+	/**
+	 * Add a listener that listens to all events appropriate to that listener,
+	 * regardless of the aspect name associated with that event.
+	 * The listener cannot be null.
+	 */
+	protected <T extends ChangeListener> void addListener(Class<T> listenerClass, T listener) {
+		if (listener == null) {
+			throw new NullPointerException();		// better sooner than later
+		}
+		synchronized (this) {
+			GenericListenerList gll = this.genericListenerList(listenerClass);
+			if (gll == null) {
+				this.addGenericListenerList(listenerClass, listener);
+			} else {
+				gll.addListener(listener);
+			}
+		}
+	}
+
+	/**
+	 * Return the generic listener list for the specified listener class.
+	 * Return null if the list is not present.
+	 */
+	protected GenericListenerList genericListenerList(Class<? extends ChangeListener> listenerClass) {
+		for (GenericListenerList gll : this.genericListeners) {
+			if (gll.listenerClass == listenerClass) {
+				return gll;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Add the generic listener list for the specified listener class.
+	 * Return the newly-built generic listener list.
+	 */
+	protected <T extends ChangeListener> GenericListenerList addGenericListenerList(Class<T> listenerClass, T listener) {
+		GenericListenerList gll = new GenericListenerList(listenerClass, listener);
+		this.genericListeners = CollectionTools.add(this.genericListeners, gll);
+		return gll;
+	}
+
+	/**
+	 * Adds a listener that listens to all events appropriate to that listener,
+	 * and only to those events carrying the aspect name specified.
+	 * The aspect name cannot be null and the listener cannot be null.
+	 */
+	protected <T extends ChangeListener> void addListener(String aspectName, Class<T> listenerClass, T listener) {
+		if ((aspectName == null) || (listener == null)) {
+			throw new NullPointerException();		// better sooner than later
+		}
+		synchronized (this) {
+			ChangeSupport child = this.child(aspectName);
+			if (child == null) {
+				child = this.addChild(aspectName);
+			}
+			child.addListener(listenerClass, listener);
+		}
+	}
+
+	/**
+	 * Return the child change support for the specified aspect name.
+	 * Return null if the aspect name is null or the child is not present.
+	 */
+	protected ChangeSupport child(String aspectName) {
+		// put in a null check to simplify calling code
+		if (aspectName == null) {
+			return null;
+		}
+		for (AspectChild aspectChild : this.aspectChildren) {
+			if (aspectChild.aspectName.equals(aspectName)) {
+				return aspectChild.child;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Add the child change support for the specified aspect name.
+	 * Return the newly-built child change support.
+	 */
+	protected ChangeSupport addChild(String aspectName) {
+		ChangeSupport child = this.buildChildChangeSupport();
+		this.aspectChildren = CollectionTools.add(this.aspectChildren, new AspectChild(aspectName, child));
+		return child;
+	}
+
+	/**
+	 * Build and return a child change support to hold aspect-specific listeners.
+	 */
+	protected ChangeSupport buildChildChangeSupport() {
+		return new ChangeSupport(this.source);
+	}
+
+	/**
+	 * Removes a listener that has been registered for all events appropriate to that listener.
+	 */
+	protected <T extends ChangeListener> void removeListener(Class<T> listenerClass, T listener) {
+		synchronized (this) {
+			GenericListenerList gll = this.genericListenerList(listenerClass);
+			if (gll == null) {
+				throw new IllegalArgumentException("listener not registered");
+			}
+			if ( ! gll.removeListener(listener)) {  // leave the GLL, even if it is empty?
+				throw new IllegalArgumentException("listener not registered");
+			}
+		}
+	}
+
+	/**
+	 * Removes a listener that has been registered for appropriate
+	 * events carrying the specified aspect name.
+	 */
+	protected <T extends ChangeListener> void removeListener(String aspectName, Class<T> listenerClass, T listener) {
+		synchronized (this) {
+			ChangeSupport child = this.child(aspectName);
+			if (child == null) {
+				throw new IllegalArgumentException("listener not registered");
+			}
+			child.removeListener(listenerClass, listener);  // leave the child, even if it is empty?
+		}
+	}
+
+
+	// ********** internal queries **********
+
+	/**
+	 * Return a dispatcher that will forward change notifications to the listeners.
+	 */
+	protected ChangeEventDispatcher dispatcher() {
+		return DefaultChangeEventDispatcher.instance();
+	}
+
+	/**
+	 * Return the listeners for the specified listener class.
+	 * Return null if there are no listeners.
+	 */
+	protected ChangeListener[] listeners(Class<? extends ChangeListener> listenerClass) {
+		GenericListenerList gll = this.genericListenerList(listenerClass);
+		return (gll == null) ? null : gll.listeners;
+	}
+
+	/**
+	 * Return whether there are any "generic" listeners for the specified
+	 * listener class.
+	 */
+	protected synchronized <T extends ChangeListener> boolean hasAnyListeners(Class<T> listenerClass) {
+		GenericListenerList gll = this.genericListenerList(listenerClass);
+		return (gll != null) && gll.hasListeners();
+	}
+
+	/**
+	 * Return whether there are any listeners for the specified
+	 * listener class and aspect name.
+	 */
+	protected synchronized boolean hasAnyListeners(Class<? extends ChangeListener> listenerClass, String aspectName) {
+		if (this.hasAnyListeners(listenerClass)) {
+			return true;		// there's a "generic" listener
+		}
+		ChangeSupport child = this.child(aspectName);
+		return (child != null) &&
+			child.hasAnyListeners(listenerClass);
+	}
+
+
+	// ********** behavior **********
+
+	/**
+	 * The specified aspect of the source has changed;
+	 * override this method to perform things like setting a
+	 * dirty flag or validating the source's state.
+	 * The aspect ID will be null if a "state change" occurred.
+	 */
+	protected void sourceChanged(String aspectName) {
+		// the default is to do nothing
+	}
+
+
+	// ********** state change support **********
+
+	private static final Class<StateChangeListener> STATE_CHANGE_LISTENER_CLASS = StateChangeListener.class;
+
+	/**
+	 * Add a state change listener.
+	 */
+	public void addStateChangeListener(StateChangeListener listener) {
+		this.addListener(STATE_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a state change listener.
+	 */
+	public void removeStateChangeListener(StateChangeListener listener) {
+		this.removeListener(STATE_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Return whether there are any state change listeners.
+	 */
+	public boolean hasAnyStateChangeListeners() {
+		return this.hasAnyListeners(STATE_CHANGE_LISTENER_CLASS);
+	}
+
+	private StateChangeListener[] stateChangeListeners() {
+		return (StateChangeListener[]) this.listeners(STATE_CHANGE_LISTENER_CLASS);
+	}
+
+	/**
+	 * Fire the specified state change event to any registered listeners.
+	 */
+	public void fireStateChanged(StateChangeEvent event) {
+
+		StateChangeListener[] stateChangeListeners = null;
+		StateChangeListener[] targets = null;
+
+		synchronized (this) {
+			stateChangeListeners = this.stateChangeListeners();
+			if (stateChangeListeners != null) {
+				targets = stateChangeListeners.clone();
+			}
+		}
+
+		if (targets != null) {
+			for (StateChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.stateChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().stateChanged(target, event);
+				}
+			}
+		}
+
+		this.sourceChanged(null);
+	}
+
+	/**
+	 * Report a generic state change event to any registered state change listeners.
+	 */
+	public void fireStateChanged() {
+//		this.fireStateChange(new StateChangeEvent(this.source));
+
+		StateChangeListener[] stateChangeListeners = null;
+		StateChangeListener[] targets = null;
+
+		synchronized (this) {
+			stateChangeListeners = this.stateChangeListeners();
+			if (stateChangeListeners != null) {
+				targets = stateChangeListeners.clone();
+			}
+		}
+
+		if (targets != null) {
+			StateChangeEvent event = null;
+			for (StateChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.stateChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new StateChangeEvent(this.source);
+					}
+					this.dispatcher().stateChanged(target, event);
+				}
+			}
+		}
+
+		this.sourceChanged(null);
+	}
+
+
+	// ********** property change support **********
+
+	private static final Class<PropertyChangeListener> PROPERTY_CHANGE_LISTENER_CLASS = PropertyChangeListener.class;
+
+	/**
+	 * Return whether the values are equal, with the appropriate null checks.
+	 * Convenience method for checking whether an attribute value has changed.
+	 */
+	public boolean valuesAreEqual(Object value1, Object value2) {
+		if ((value1 == null) && (value2 == null)) {
+			return true;	// both are null
+		}
+		if ((value1 == null) || (value2 == null)) {
+			return false;	// one is null but the other is not
+		}
+		return value1.equals(value2);
+	}
+
+	/**
+	 * Return whether the values are different, with the appropriate null checks.
+	 * Convenience method for checking whether an attribute value has changed.
+	 */
+	public boolean valuesAreDifferent(Object value1, Object value2) {
+		return ! this.valuesAreEqual(value1, value2);
+	}
+
+	/**
+	 * Add a property change listener that is registered for all properties.
+	 */
+	public void addPropertyChangeListener(PropertyChangeListener listener) {
+		this.addListener(PROPERTY_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Add a property change listener for the specified property. The listener
+	 * will be notified only for changes to the specified property.
+	 */
+	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		this.addListener(propertyName, PROPERTY_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a property change listener that was registered for all properties.
+	 */
+	public void removePropertyChangeListener(PropertyChangeListener listener) {
+		this.removeListener(PROPERTY_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a property change listener that was registered for a specific property.
+	 */
+	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		this.removeListener(propertyName, PROPERTY_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Return whether there are any property change listeners that will
+	 * be notified when the specified property has changed.
+	 */
+	public boolean hasAnyPropertyChangeListeners(String propertyName) {
+		return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS, propertyName);
+	}
+
+	/**
+	 * Return whether there are any property change listeners that will
+	 * be notified when any property has changed.
+	 */
+	public boolean hasAnyPropertyChangeListeners() {
+		return this.hasAnyListeners(PROPERTY_CHANGE_LISTENER_CLASS);
+	}
+
+	private PropertyChangeListener[] propertyChangeListeners() {
+		return (PropertyChangeListener[]) this.listeners(PROPERTY_CHANGE_LISTENER_CLASS);
+	}
+
+	/**
+	 * Fire the specified property change event to any registered listeners.
+	 * No event is fired if the given event's old and new values are the same;
+	 * this includes when both values are null. Use a state change event
+	 * for general purpose notification of changes.
+	 */
+	public void firePropertyChanged(PropertyChangeEvent event) {
+		if (this.valuesAreEqual(event.oldValue(), event.newValue())) {
+			return; 
+		}
+
+		String propertyName = event.propertyName();
+
+		PropertyChangeListener[] propertyChangeListeners = null;
+		PropertyChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			propertyChangeListeners = this.propertyChangeListeners();
+			if (propertyChangeListeners != null) {
+				targets = propertyChangeListeners.clone();
+			}
+			child = this.child(propertyName);
+		}
+
+		if (targets != null) {
+			for (PropertyChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.propertyChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().propertyChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.firePropertyChanged(event);
+		}
+
+		this.sourceChanged(propertyName);
+	}
+
+	/**
+	 * Report a bound property update to any registered property change listeners.
+	 * No event is fired if the given old and new values are the same;
+	 * this includes when both values are null. Use a state change event
+	 * for general purpose notification of changes.
+	 */
+	public void firePropertyChanged(String propertyName, Object oldValue, Object newValue) {
+//		this.firePropertyChanged(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
+		if (this.valuesAreEqual(oldValue, newValue)) {
+			return;
+		}
+
+		PropertyChangeListener[] propertyChangeListeners = null;
+		PropertyChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			propertyChangeListeners = this.propertyChangeListeners();
+			if (propertyChangeListeners != null) {
+				targets = propertyChangeListeners.clone();
+			}
+			child = this.child(propertyName);
+		}
+
+		PropertyChangeEvent event = null;
+
+		if (targets != null) {
+			for (PropertyChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.propertyChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new PropertyChangeEvent(this.source, propertyName, oldValue, newValue);
+					}
+					this.dispatcher().propertyChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.firePropertyChanged(propertyName, oldValue, newValue);
+			} else {
+				child.firePropertyChanged(event);
+			}
+		}
+
+		this.sourceChanged(propertyName);
+	}
+
+	/**
+	 * Report an int bound property update to any registered listeners.
+	 * No event is fired if old and new are equal.
+	 * <p>
+	 * This is merely a convenience wrapper around the more general
+	 * firePropertyChange method that takes Object values.
+	 */
+	public void firePropertyChanged(String propertyName, int oldValue, int newValue) {
+//		this.firePropertyChanged(propertyName, new Integer(oldValue), new Integer(newValue));
+		if (oldValue == newValue) {
+			return;
+		}
+
+		PropertyChangeListener[] propertyChangeListeners = null;
+		PropertyChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			propertyChangeListeners = this.propertyChangeListeners();
+			if (propertyChangeListeners != null) {
+				targets = propertyChangeListeners.clone();
+			}
+			child = this.child(propertyName);
+		}
+
+		PropertyChangeEvent event = null;
+
+		if (targets != null) {
+			for (PropertyChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.propertyChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new PropertyChangeEvent(this.source, propertyName, new Integer(oldValue), new Integer(newValue));
+					}
+					this.dispatcher().propertyChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.firePropertyChanged(propertyName, oldValue, newValue);
+			} else {
+				child.firePropertyChanged(event);
+			}
+		}
+
+		this.sourceChanged(propertyName);
+	}
+
+	/**
+	 * Report a boolean bound property update to any registered listeners.
+	 * No event is fired if old and new are equal.
+	 * <p>
+	 * This is merely a convenience wrapper around the more general
+	 * firePropertyChange method that takes Object values.
+	 */
+	public void firePropertyChanged(String propertyName, boolean oldValue, boolean newValue) {
+//		this.firePropertyChanged(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+		if (oldValue == newValue) {
+			return;
+		}
+
+		PropertyChangeListener[] propertyChangeListeners = null;
+		PropertyChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			propertyChangeListeners = this.propertyChangeListeners();
+			if (propertyChangeListeners != null) {
+				targets = propertyChangeListeners.clone();
+			}
+			child = this.child(propertyName);
+		}
+
+		PropertyChangeEvent event = null;
+
+		if (targets != null) {
+			for (PropertyChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.propertyChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new PropertyChangeEvent(this.source, propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+					}
+					this.dispatcher().propertyChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.firePropertyChanged(propertyName, oldValue, newValue);
+			} else {
+				child.firePropertyChanged(event);
+			}
+		}
+
+		this.sourceChanged(propertyName);
+	}
+
+
+	// ********** collection change support **********
+
+	private static final Class<CollectionChangeListener> COLLECTION_CHANGE_LISTENER_CLASS = CollectionChangeListener.class;
+
+	/**
+	 * Add a collection change listener that is registered for all collections.
+	 */
+	public void addCollectionChangeListener(CollectionChangeListener listener) {
+		this.addListener(COLLECTION_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Add a collection change listener for the specified collection. The listener
+	 * will be notified only for changes to the specified collection.
+	 */
+	public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		this.addListener(collectionName, COLLECTION_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a collection change listener that was registered for all collections.
+	 */
+	public void removeCollectionChangeListener(CollectionChangeListener listener) {
+		this.removeListener(COLLECTION_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a collection change listener that was registered for a specific collection.
+	 */
+	public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		this.removeListener(collectionName, COLLECTION_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Return whether there are any collection change listeners that will
+	 * be notified when the specified collection has changed.
+	 */
+	public boolean hasAnyCollectionChangeListeners(String collectionName) {
+		return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS, collectionName);
+	}
+
+	/**
+	 * Return whether there are any collection change listeners that will
+	 * be notified when any collection has changed.
+	 */
+	public boolean hasAnyCollectionChangeListeners() {
+		return this.hasAnyListeners(COLLECTION_CHANGE_LISTENER_CLASS);
+	}
+
+	private CollectionChangeListener[] collectionChangeListeners() {
+		return (CollectionChangeListener[]) this.listeners(COLLECTION_CHANGE_LISTENER_CLASS);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireItemsAdded(CollectionChangeEvent event) {
+		if (event.itemsSize() == 0) {
+			return;
+		}
+
+		String collectionName = event.collectionName();
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().itemsAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireItemsAdded(event);
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireItemsAdded(String collectionName, Collection<?> addedItems) {
+//		this.fireItemsAdded(new CollectionChangeEvent(this.source, collectionName, addedItems));
+		if (addedItems.size() == 0) {
+			return;
+		}
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		CollectionChangeEvent event = null;
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new CollectionChangeEvent(this.source, collectionName, addedItems);
+					}
+					this.dispatcher().itemsAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemsAdded(collectionName, addedItems);
+			} else {
+				child.fireItemsAdded(event);
+			}
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireItemAdded(String collectionName, Object addedItem) {
+//		this.fireItemsAdded(collectionName, Collections.singleton(addedItem));
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		CollectionChangeEvent event = null;
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new CollectionChangeEvent(this.source, collectionName, Collections.singleton(addedItem));
+					}
+					this.dispatcher().itemsAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemAdded(collectionName, addedItem);
+			} else {
+				child.fireItemsAdded(event);
+			}
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireItemsRemoved(CollectionChangeEvent event) {
+		if (event.itemsSize() == 0) {
+			return;
+		}
+
+		String collectionName = event.collectionName();
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().itemsRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireItemsRemoved(event);
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireItemsRemoved(String collectionName, Collection<?> removedItems) {
+//		this.fireItemsRemoved(new CollectionChangeEvent(this.source, collectionName, removedItems));
+		if (removedItems.size() == 0) {
+			return;
+		}
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		CollectionChangeEvent event = null;
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new CollectionChangeEvent(this.source, collectionName, removedItems);
+					}
+					this.dispatcher().itemsRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemsRemoved(collectionName, removedItems);
+			} else {
+				child.fireItemsRemoved(event);
+			}
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireItemRemoved(String collectionName, Object removedItem) {
+//		this.fireItemsRemoved(collectionName, Collections.singleton(removedItem));
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		CollectionChangeEvent event = null;
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new CollectionChangeEvent(this.source, collectionName, Collections.singleton(removedItem));
+					}
+					this.dispatcher().itemsRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemRemoved(collectionName, removedItem);
+			} else {
+				child.fireItemsRemoved(event);
+			}
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireCollectionCleared(CollectionChangeEvent event) {
+		String collectionName = event.collectionName();
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().collectionCleared(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireCollectionCleared(event);
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireCollectionCleared(String collectionName) {
+//		this.fireCollectionCleared(new CollectionChangeEvent(this.source, collectionName));
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		CollectionChangeEvent event = null;
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new CollectionChangeEvent(this.source, collectionName);
+					}
+					this.dispatcher().collectionCleared(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireCollectionCleared(collectionName);
+			} else {
+				child.fireCollectionCleared(event);
+			}
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireCollectionChanged(CollectionChangeEvent event) {
+		String collectionName = event.collectionName();
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().collectionChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireCollectionChanged(event);
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+	/**
+	 * Report a bound collection update to any registered listeners.
+	 */
+	public void fireCollectionChanged(String collectionName) {
+//		this.fireCollectionChanged(new CollectionChangeEvent(this.source, collectionName));
+
+		CollectionChangeListener[] collectionChangeListeners = null;
+		CollectionChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			collectionChangeListeners = this.collectionChangeListeners();
+			if (collectionChangeListeners != null) {
+				targets = collectionChangeListeners.clone();
+			}
+			child = this.child(collectionName);
+		}
+
+		CollectionChangeEvent event = null;
+
+		if (targets != null) {
+			for (CollectionChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.collectionChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new CollectionChangeEvent(this.source, collectionName);
+					}
+					this.dispatcher().collectionChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireCollectionChanged(collectionName);
+			} else {
+				child.fireCollectionChanged(event);
+			}
+		}
+
+		this.sourceChanged(collectionName);
+	}
+
+
+	// ********** list change support **********
+
+	private static final Class<ListChangeListener> LIST_CHANGE_LISTENER_CLASS = ListChangeListener.class;
+
+	/**
+	 * Add a list change listener that is registered for all lists.
+	 */
+	public void addListChangeListener(ListChangeListener listener) {
+		this.addListener(LIST_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Add a list change listener for the specified list. The listener
+	 * will be notified only for changes to the specified list.
+	 */
+	public void addListChangeListener(String listName, ListChangeListener listener) {
+		this.addListener(listName, LIST_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a list change listener that was registered for all lists.
+	 */
+	public void removeListChangeListener(ListChangeListener listener) {
+		this.removeListener(LIST_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a list change listener that was registered for a specific list.
+	 */
+	public void removeListChangeListener(String listName, ListChangeListener listener) {
+		this.removeListener(listName, LIST_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Return whether there are any list change listeners that will
+	 * be notified when the specified list has changed.
+	 */
+	public boolean hasAnyListChangeListeners(String listName) {
+		return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS, listName);
+	}
+
+	/**
+	 * Return whether there are any list change listeners that will
+	 * be notified when any list has changed.
+	 */
+	public boolean hasAnyListChangeListeners() {
+		return this.hasAnyListeners(LIST_CHANGE_LISTENER_CLASS);
+	}
+
+	private ListChangeListener[] listChangeListeners() {
+		return (ListChangeListener[]) this.listeners(LIST_CHANGE_LISTENER_CLASS);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsAdded(ListChangeEvent event) {
+		if (event.itemsSize() == 0) {
+			return;
+		}
+
+		String listName = event.listName();
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().itemsAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireItemsAdded(event);
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsAdded(String listName, int index, List<?> addedItems) {
+//		this.fireItemsAdded(new ListChangeEvent(this.source, listName, index, addedItems));
+		if (addedItems.size() == 0) {
+			return;
+		}
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, index, addedItems);
+					}
+					this.dispatcher().itemsAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemsAdded(listName, index, addedItems);
+			} else {
+				child.fireItemsAdded(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemAdded(String listName, int index, Object addedItem) {
+//		this.fireItemsAdded(listName, index, Collections.singletonList(addedItem));
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(addedItem));
+					}
+					this.dispatcher().itemsAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemAdded(listName, index, addedItem);
+			} else {
+				child.fireItemsAdded(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsRemoved(ListChangeEvent event) {
+		if (event.itemsSize() == 0) {
+			return;
+		}
+
+		String listName = event.listName();
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().itemsRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireItemsRemoved(event);
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsRemoved(String listName, int index, List<?> removedItems) {
+//		this.fireItemsRemoved(new ListChangeEvent(this.source, listName, index, removedItems));
+		if (removedItems.size() == 0) {
+			return;
+		}
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, index, removedItems);
+					}
+					this.dispatcher().itemsRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemsRemoved(listName, index, removedItems);
+			} else {
+				child.fireItemsRemoved(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemRemoved(String listName, int index, Object removedItem) {
+//		this.fireItemsRemoved(listName, index, Collections.singletonList(removedItem));
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(removedItem));
+					}
+					this.dispatcher().itemsRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemRemoved(listName, index, removedItem);
+			} else {
+				child.fireItemsRemoved(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsReplaced(ListChangeEvent event) {
+		if (event.itemsSize() == 0) {
+			return;
+		}
+
+		String listName = event.listName();
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().itemsReplaced(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireItemsReplaced(event);
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsReplaced(String listName, int index, List<?> newItems, List<?> replacedItems) {
+//		this.fireItemsReplaced(new ListChangeEvent(this.source, listName, index, newItems, replacedItems));
+		if (newItems.size() == 0) {
+			return;
+		}
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, index, newItems, replacedItems);
+					}
+					this.dispatcher().itemsReplaced(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemsReplaced(listName, index, newItems, replacedItems);
+			} else {
+				child.fireItemsReplaced(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemReplaced(String listName, int index, Object newItem, Object replacedItem) {
+//		this.fireItemsReplaced(listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem));
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, index, Collections.singletonList(newItem), Collections.singletonList(replacedItem));
+					}
+					this.dispatcher().itemsReplaced(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemReplaced(listName, index, newItem, replacedItem);
+			} else {
+				child.fireItemsReplaced(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsMoved(ListChangeEvent event) {
+		if (event.targetIndex() == event.sourceIndex()) {
+			return;
+		}
+
+		String listName = event.listName();
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().itemsMoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireItemsMoved(event);
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemsMoved(String listName, int targetIndex, int sourceIndex, int length) {
+//		this.fireItemsMoved(new ListChangeEvent(this.source, listName, targetIndex, sourceIndex, length));
+		if (targetIndex == sourceIndex) {
+			return;
+		}
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName, targetIndex, sourceIndex, length);
+					}
+					this.dispatcher().itemsMoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireItemsMoved(listName, targetIndex, sourceIndex, length);
+			} else {
+				child.fireItemsMoved(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireItemMoved(String listName, int targetIndex, int sourceIndex) {
+		this.fireItemsMoved(listName, targetIndex, sourceIndex, 1);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireListCleared(ListChangeEvent event) {
+		String listName = event.listName();
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().listCleared(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireListCleared(event);
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireListCleared(String listName) {
+//		this.fireListCleared(new ListChangeEvent(this.source, listName));
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName);
+					}
+					this.dispatcher().listCleared(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireListCleared(listName);
+			} else {
+				child.fireListCleared(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireListChanged(ListChangeEvent event) {
+		String listName = event.listName();
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().listChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireListChanged(event);
+		}
+
+		this.sourceChanged(listName);
+	}
+
+	/**
+	 * Report a bound list update to any registered listeners.
+	 */
+	public void fireListChanged(String listName) {
+//		this.fireListChanged(new ListChangeEvent(this.source, listName));
+
+		ListChangeListener[] listChangeListeners = null;
+		ListChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			listChangeListeners = this.listChangeListeners();
+			if (listChangeListeners != null) {
+				targets = listChangeListeners.clone();
+			}
+			child = this.child(listName);
+		}
+
+		ListChangeEvent event = null;
+
+		if (targets != null) {
+			for (ListChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.listChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new ListChangeEvent(this.source, listName);
+					}
+					this.dispatcher().listChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireListChanged(listName);
+			} else {
+				child.fireListChanged(event);
+			}
+		}
+
+		this.sourceChanged(listName);
+	}
+
+
+	// ********** tree change support **********
+
+	private static final Class<TreeChangeListener> TREE_CHANGE_LISTENER_CLASS = TreeChangeListener.class;
+	private static final Object[] EMPTY_TREE_PATH = new Object[0];
+
+	/**
+	 * Add a tree change listener that is registered for all trees.
+	 */
+	public void addTreeChangeListener(TreeChangeListener listener) {
+		this.addListener(TREE_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Add a tree change listener for the specified tree. The listener
+	 * will be notified only for changes to the specified tree.
+	 */
+	public void addTreeChangeListener(String treeName, TreeChangeListener listener) {
+		this.addListener(treeName, TREE_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a tree change listener that was registered for all tree.
+	 */
+	public void removeTreeChangeListener(TreeChangeListener listener) {
+		this.removeListener(TREE_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Remove a tree change listener that was registered for a specific tree.
+	 */
+	public void removeTreeChangeListener(String treeName, TreeChangeListener listener) {
+		this.removeListener(treeName, TREE_CHANGE_LISTENER_CLASS, listener);
+	}
+
+	/**
+	 * Return whether there are any tree change listeners that will
+	 * be notified when the specified tree has changed.
+	 */
+	public boolean hasAnyTreeChangeListeners(String treeName) {
+		return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS, treeName);
+	}
+
+	/**
+	 * Return whether there are any tree change listeners that will
+	 * be notified when any tree has changed.
+	 */
+	public boolean hasAnyTreeChangeListeners() {
+		return this.hasAnyListeners(TREE_CHANGE_LISTENER_CLASS);
+	}
+
+	private TreeChangeListener[] treeChangeListeners() {
+		return (TreeChangeListener[]) this.listeners(TREE_CHANGE_LISTENER_CLASS);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireNodeAdded(TreeChangeEvent event) {
+		String treeName = event.treeName();
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().nodeAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireNodeAdded(event);
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireNodeAdded(String treeName, Object[] path) {
+//		this.fireNodeAdded(new TreeChangeEvent(this.source, treeName, path));
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		TreeChangeEvent event = null;
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new TreeChangeEvent(this.source, treeName, path);
+					}
+					this.dispatcher().nodeAdded(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireNodeAdded(treeName, path);
+			} else {
+				child.fireNodeAdded(event);
+			}
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireNodeRemoved(TreeChangeEvent event) {
+		String treeName = event.treeName();
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().nodeRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireNodeRemoved(event);
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireNodeRemoved(String treeName, Object[] path) {
+//		this.fireNodeRemoved(new TreeChangeEvent(this.source, treeName, path));
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		TreeChangeEvent event = null;
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new TreeChangeEvent(this.source, treeName, path);
+					}
+					this.dispatcher().nodeRemoved(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireNodeRemoved(treeName, path);
+			} else {
+				child.fireNodeRemoved(event);
+			}
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireTreeCleared(TreeChangeEvent event) {
+		String treeName = event.treeName();
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().treeCleared(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireTreeCleared(event);
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireTreeCleared(String treeName, Object[] path) {
+//		this.fireTreeCleared(new TreeChangeEvent(this.source, treeName, path));
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		TreeChangeEvent event = null;
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new TreeChangeEvent(this.source, treeName, path);
+					}
+					this.dispatcher().treeCleared(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireTreeCleared(treeName, path);
+			} else {
+				child.fireTreeCleared(event);
+			}
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireTreeCleared(String treeName) {
+		this.fireTreeCleared(treeName, EMPTY_TREE_PATH);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireTreeChanged(TreeChangeEvent event) {
+		String treeName = event.treeName();
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					this.dispatcher().treeChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			child.fireTreeChanged(event);
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireTreeChanged(String treeName, Object[] path) {
+//		this.fireTreeChanged(new TreeChangeEvent(this.source, treeName, path));
+
+		TreeChangeListener[] treeChangeListeners = null;
+		TreeChangeListener[] targets = null;
+		ChangeSupport child = null;
+
+		synchronized (this) {
+			treeChangeListeners = this.treeChangeListeners();
+			if (treeChangeListeners != null) {
+				targets = treeChangeListeners.clone();
+			}
+			child = this.child(treeName);
+		}
+
+		TreeChangeEvent event = null;
+
+		if (targets != null) {
+			for (TreeChangeListener target : targets) {
+				boolean stillListening;
+				synchronized (this) {
+					stillListening = CollectionTools.contains(this.treeChangeListeners(), target);
+				}
+				if (stillListening) {
+					if (event == null) {
+						// here's the reason for the duplicate code...
+						event = new TreeChangeEvent(this.source, treeName, path);
+					}
+					this.dispatcher().treeChanged(target, event);
+				}
+			}
+		}
+		if (child != null) {
+			if (event == null) {
+				child.fireTreeChanged(treeName, path);
+			} else {
+				child.fireTreeChanged(event);
+			}
+		}
+
+		this.sourceChanged(treeName);
+	}
+
+	/**
+	 * Report a bound tree update to any registered listeners.
+	 */
+	public void fireTreeChanged(String treeName) {
+		this.fireTreeChanged(treeName, EMPTY_TREE_PATH);
+	}
+
+
+	// ********** standard methods **********
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.source);
+	}
+
+
+	// ********** serialization **********
+
+	private synchronized void writeObject(ObjectOutputStream s) throws IOException {
+		// write out the source, children, and any hidden stuff
+		s.defaultWriteObject();
+
+		// only write out Serializable listeners
+		int len1 = this.genericListeners.length;
+		for (int i = 0; i < len1; i++) {
+			this.writeObject(s, this.genericListeners[i]);
+		}
+		s.writeObject(null);
+    }
+
+	private void writeObject(ObjectOutputStream s, GenericListenerList gll) throws IOException {
+		boolean first = true;
+		int len = gll.listeners.length;
+		for (int i = 0; i < len; i++) {
+			ChangeListener listener = gll.listeners[i];
+			if (listener instanceof Serializable) {
+				if (first) {
+					first = false;
+					s.writeObject(gll.listenerClass);
+				}
+				s.writeObject(listener);
+			}
+		}
+		if ( ! first) {
+			s.writeObject(null);
+		}
+	}
+
+	private synchronized void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
+		// read in the source, children, and any hidden stuff
+		s.defaultReadObject();
+
+		// read in generic listener lists
+		this.genericListeners = EMPTY_GENERIC_LISTENERS;
+		Object o;
+		while (null != (o = s.readObject())) {
+			@SuppressWarnings("unchecked")
+			Class<? extends ChangeListener> listenerClass = (Class<? extends ChangeListener>) o;
+			GenericListenerList gll = null;
+			while (null != (o = s.readObject())) {
+				if (gll == null) {
+					gll = this.addGenericListenerListInternal(listenerClass, (ChangeListener) o);
+				} else {
+					gll.addListener((ChangeListener) o);
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T extends ChangeListener> GenericListenerList addGenericListenerListInternal(Class<T> listenerClass, ChangeListener listener) {
+		return this.addGenericListenerList(listenerClass, (T) listener);
+	}
+
+
+	// ********** member classes **********
+
+	/**
+	 * Pair a listener class with its generic listeners.
+	 */
+	private static class GenericListenerList {
+		final Class<? extends ChangeListener> listenerClass;
+		ChangeListener[] listeners;
+		<T extends ChangeListener> GenericListenerList(Class<T> listenerClass, T listener) {
+			super();
+			this.listenerClass = listenerClass;
+			this.listeners = (ChangeListener[]) Array.newInstance(listenerClass, 1);
+			this.listeners[0] = listener;
+		}
+		void addListener(ChangeListener listener) {
+			this.listeners = CollectionTools.add(this.listeners, listener);
+		}
+		boolean removeListener(ChangeListener listener) {
+			int len = this.listeners.length;
+			if (len == 0) {
+				return false;
+			}
+			try {
+				this.listeners = CollectionTools.remove(this.listeners, listener);
+			} catch (ArrayIndexOutOfBoundsException ex) {
+				return false;  // listener not in the list
+			}
+			return (this.listeners.length + 1) == len;
+		}
+		boolean hasListeners() {
+			return this.listeners.length > 0;
+		}
+	}
+
+	/**
+	 * Pair an aspect name with the change support holding its associated
+	 * listeners.
+	 */
+	private static class AspectChild implements Serializable {
+		final String aspectName;
+		final ChangeSupport child;
+		private static final long serialVersionUID = 1L;
+		AspectChild(String aspectName, ChangeSupport child) {
+			super();
+			this.aspectName = aspectName;
+			this.child = child;
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/DefaultChangeEventDispatcher.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/DefaultChangeEventDispatcher.java
new file mode 100644
index 0000000..f6433b1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/DefaultChangeEventDispatcher.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import java.io.Serializable;
+
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Straightforward implementation of ChangeEventDispatcher interface:
+ * Just forward the change notification directly to the listener.
+ */
+public class DefaultChangeEventDispatcher
+	implements ChangeEventDispatcher, Serializable
+{
+	// singleton
+	private static ChangeEventDispatcher INSTANCE;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Return the singleton.
+	 */
+	public synchronized static ChangeEventDispatcher instance() {
+		if (INSTANCE == null) {
+			INSTANCE = new DefaultChangeEventDispatcher();
+		}
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private DefaultChangeEventDispatcher() {
+		super();
+	}
+
+	public void stateChanged(StateChangeListener listener, StateChangeEvent event) {
+		listener.stateChanged(event);
+	}
+
+	public void propertyChanged(PropertyChangeListener listener, PropertyChangeEvent event) {
+		listener.propertyChanged(event);
+	}
+
+	public void itemsAdded(CollectionChangeListener listener, CollectionChangeEvent event) {
+		listener.itemsAdded(event);
+	}
+
+	public void itemsRemoved(CollectionChangeListener listener, CollectionChangeEvent event) {
+		listener.itemsRemoved(event);
+	}
+
+	public void collectionCleared(CollectionChangeListener listener, CollectionChangeEvent event) {
+		listener.collectionCleared(event);
+	}
+
+	public void collectionChanged(CollectionChangeListener listener, CollectionChangeEvent event) {
+		listener.collectionChanged(event);
+	}
+
+	public void itemsAdded(ListChangeListener listener, ListChangeEvent event) {
+		listener.itemsAdded(event);
+	}
+
+	public void itemsRemoved(ListChangeListener listener, ListChangeEvent event) {
+		listener.itemsRemoved(event);
+	}
+
+	public void itemsReplaced(ListChangeListener listener, ListChangeEvent event) {
+		listener.itemsReplaced(event);
+	}
+
+	public void itemsMoved(ListChangeListener listener, ListChangeEvent event) {
+		listener.itemsMoved(event);
+	}
+
+	public void listCleared(ListChangeListener listener, ListChangeEvent event) {
+		listener.listCleared(event);
+	}
+
+	public void listChanged(ListChangeListener listener, ListChangeEvent event) {
+		listener.listChanged(event);
+	}
+
+	public void nodeAdded(TreeChangeListener listener, TreeChangeEvent event) {
+		listener.nodeAdded(event);
+	}
+
+	public void nodeRemoved(TreeChangeListener listener, TreeChangeEvent event) {
+		listener.nodeRemoved(event);
+	}
+
+	public void treeCleared(TreeChangeListener listener, TreeChangeEvent event) {
+		listener.treeCleared(event);
+	}
+
+	public void treeChanged(TreeChangeListener listener, TreeChangeEvent event) {
+		listener.treeChanged(event);
+	}
+
+	/**
+	 * Serializable singleton support
+	 */
+	private Object readResolve() {
+		return instance();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/Model.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/Model.java
new file mode 100644
index 0000000..fc3916d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/Model.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Interface to be implemented by models that notify listeners of
+ * changes to bound properties, collections, lists, and/or trees.
+ */
+public interface Model {
+
+	// ********** state change **********
+
+	/**
+	 * Add a listener that listens to all state change events.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addStateChangeListener(StateChangeListener listener);
+
+	/**
+	 * Remove the specified state change listener. If the listener
+	 * was added more than once, it will be notified one less time
+	 * after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeStateChangeListener(StateChangeListener listener);
+
+
+	// ********** property change **********
+
+	/**
+	 * Add a listener that listens to all property change events,
+	 * regardless of the property ID associated with that event.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addPropertyChangeListener(PropertyChangeListener listener);
+
+	/**
+	 * Add a listener that listens to all property change events with
+	 * the specified property ID.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all property change events,
+	 * regardless of the property ID associated with that event.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removePropertyChangeListener(PropertyChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all property change events,
+	 * with the specified property ID.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
+
+
+	// ********** collection change **********
+
+	/**
+	 * Add a listener that listens to all collection change events,
+	 * regardless of the collection ID associated with that event.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addCollectionChangeListener(CollectionChangeListener listener);
+
+	/**
+	 * Add a listener that listens to all collection change events with
+	 * the specified collection ID.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addCollectionChangeListener(String collectionName, CollectionChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all collection change events,
+	 * regardless of the collection ID associated with that event.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeCollectionChangeListener(CollectionChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all collection change events,
+	 * with the specified collection ID.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener);
+
+
+	// ********** list change **********
+
+	/**
+	 * Add a listener that listens to all list change events,
+	 * regardless of the list ID associated with that event.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addListChangeListener(ListChangeListener listener);
+
+	/**
+	 * Add a listener that listens to all list change events with
+	 * the specified list ID.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addListChangeListener(String listName, ListChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all list change events,
+	 * regardless of the list ID associated with that event.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeListChangeListener(ListChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all list change events,
+	 * with the specified list ID.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeListChangeListener(String listName, ListChangeListener listener);
+
+
+	// ********** tree change **********
+
+	/**
+	 * Add a listener that listens to all tree change events,
+	 * regardless of the tree ID associated with that event.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addTreeChangeListener(TreeChangeListener listener);
+
+	/**
+	 * Add a listener that listens to all tree change events with
+	 * the specified tree ID.
+	 * The same listener may be added more than once and will be called
+	 * as many times as it is added. The listener cannot be null.
+	 */
+	void addTreeChangeListener(String treeName, TreeChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all tree change events,
+	 * regardless of the tree ID associated with that event.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeTreeChangeListener(TreeChangeListener listener);
+
+	/**
+	 * Remove a listener that listens to all tree change events,
+	 * with the specified tree ID.
+	 * If the listener was added more than once, it will be notified one less
+	 * time after being removed. An exception will be thrown if the
+	 * listener is null or if the listener was never added.
+	 */
+	void removeTreeChangeListener(String treeName, TreeChangeListener listener);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/NullChangeEventDispatcher.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/NullChangeEventDispatcher.java
new file mode 100644
index 0000000..22c09c8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/NullChangeEventDispatcher.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import java.io.Serializable;
+
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Null implementation of ChangeEventDispatcher interface: Do nothing.
+ */
+public class NullChangeEventDispatcher
+	implements ChangeEventDispatcher, Serializable
+{
+	// singleton
+	private static ChangeEventDispatcher INSTANCE;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Return the singleton.
+	 */
+	public synchronized static ChangeEventDispatcher instance() {
+		if (INSTANCE == null) {
+			INSTANCE = new NullChangeEventDispatcher();
+		}
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure non-instantiability.
+	 */
+	private NullChangeEventDispatcher() {
+		super();
+	}
+
+	public void stateChanged(StateChangeListener listener, StateChangeEvent event) {
+		// do nothing
+	}
+
+	public void propertyChanged(PropertyChangeListener listener, PropertyChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsAdded(CollectionChangeListener listener, CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsRemoved(CollectionChangeListener listener, CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void collectionCleared(CollectionChangeListener listener, CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void collectionChanged(CollectionChangeListener listener, CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsAdded(ListChangeListener listener, ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsRemoved(ListChangeListener listener, ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsReplaced(ListChangeListener listener, ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsMoved(ListChangeListener listener, ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void listCleared(ListChangeListener listener, ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void listChanged(ListChangeListener listener, ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void nodeAdded(TreeChangeListener listener, TreeChangeEvent event) {
+		// do nothing
+	}
+
+	public void nodeRemoved(TreeChangeListener listener, TreeChangeEvent event) {
+		// do nothing
+	}
+
+	public void treeCleared(TreeChangeListener listener, TreeChangeEvent event) {
+		// do nothing
+	}
+
+	public void treeChanged(TreeChangeListener listener, TreeChangeEvent event) {
+		// do nothing
+	}
+
+	/**
+	 * Serializable singleton support
+	 */
+	private Object readResolve() {
+		return instance();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/NullModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/NullModel.java
new file mode 100644
index 0000000..998ff3e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/NullModel.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model;
+
+import java.io.Serializable;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+/**
+ * Null implementation that never notifies any listeners of any changes
+ * because it never changes.
+ */
+public class NullModel
+	implements Model, Cloneable, Serializable
+{
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Default constructor.
+	 */
+	public NullModel() {
+		super();
+	}
+
+
+	// ********** Model implementation **********
+
+	public void addStateChangeListener(StateChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeStateChangeListener(StateChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addPropertyChangeListener(PropertyChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removePropertyChangeListener(PropertyChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addCollectionChangeListener(CollectionChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeCollectionChangeListener(CollectionChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeCollectionChangeListener(String collectionName, CollectionChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addListChangeListener(ListChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addListChangeListener(String listName, ListChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeListChangeListener(ListChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeListChangeListener(String listName, ListChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addTreeChangeListener(TreeChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void addTreeChangeListener(String treeName, TreeChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeTreeChangeListener(TreeChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+	public void removeTreeChangeListener(String treeName, TreeChangeListener listener) {
+		// ignore listeners - nothing ever changes
+	}
+
+
+	// ********** Object overrides **********
+
+	@Override
+	public synchronized NullModel clone() {
+		try {
+			return (NullModel) super.clone();
+		} catch (CloneNotSupportedException ex) {
+			throw new InternalError();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return ClassTools.shortClassNameForObject(this);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/ChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/ChangeEvent.java
new file mode 100644
index 0000000..f5d6827
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/ChangeEvent.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.event;
+
+import java.util.EventObject;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+
+/**
+ * Abstract class for all the change events that can be fired by models.
+ */
+public abstract class ChangeEvent extends EventObject {
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a new change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 */
+	protected ChangeEvent(Object source) {
+		super(source);
+	}
+
+	/**
+	 * Return the name of the aspect of the source that changed.
+	 * May be null if inappropriate.
+	 */
+	public abstract String aspectName();
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source.
+	 */
+	public abstract ChangeEvent cloneWithSource(Object newSource);
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.aspectName());
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/CollectionChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/CollectionChangeEvent.java
new file mode 100644
index 0000000..1076be3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/CollectionChangeEvent.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.event;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * A "collection change" event gets delivered whenever a model changes a "bound"
+ * or "constrained" collection. A CollectionChangeEvent is sent as an
+ * argument to the CollectionChangeListener.
+ * 
+ * Normally a CollectionChangeEvent is accompanied by the collection name and
+ * the items that were added to or removed from the changed collection.
+ * 
+ * Design options:
+ * - create a collection to wrap a single added or removed item
+ * 	(this is the option we implemented below and in collaborating code)
+ * 	since there is no way to optimize downstream code for
+ * 	single items, we take another performance hit by building
+ * 	a collection each time  (@see Collections.singleton(Object))
+ * 	and forcing downstream code to use an iterator every time
+ * 
+ * - fire a separate event for each item added or removed
+ * 	eliminates any potential for optimizations to downstream code
+ * 
+ * - add protocol to support both single items and collections
+ * 	adds conditional logic to downstream code
+ */
+public class CollectionChangeEvent extends ChangeEvent {
+
+	/** Name of the collection that changed. */
+	private final String collectionName;
+
+	/** The items that were added to or removed from the collection. May be empty, if not known. */
+	private final Collection<?> items;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a new collection change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param collectionName The programmatic name of the collection that was changed.
+	 * @param items The items that were added to or removed from the collection.
+	 */
+	public CollectionChangeEvent(Object source, String collectionName, Collection<?> items) {
+		super(source);
+		if ((collectionName == null) || (items == null)) {
+			throw new NullPointerException();
+		}
+		this.collectionName = collectionName;
+		this.items = Collections.unmodifiableCollection(items);
+	}
+
+	/**
+	 * Construct a new collection change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param collectionName The programmatic name of the collection that was changed.
+	 */
+	@SuppressWarnings("unchecked")
+	public CollectionChangeEvent(Object source, String collectionName) {
+		this(source, collectionName, Collections.emptySet());
+	}
+
+	/**
+	 * Return the programmatic name of the collection that was changed.
+	 */
+	public String collectionName() {
+		return this.collectionName;
+	}
+
+	/**
+	 * Return an iterator on the items that were added to or
+	 * removed from the collection.
+	 * May be empty if inappropriate or unknown.
+	 */
+	public Iterator<?> items() {
+		return this.items.iterator();
+	}
+
+	/**
+	 * Return the number of items that were added to or
+	 * removed from the collection.
+	 * May be 0 if inappropriate or unknown.
+	 */
+	public int itemsSize() {
+		return this.items.size();
+	}
+
+	@Override
+	public String aspectName() {
+		return this.collectionName;
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source.
+	 */
+	@Override
+	public CollectionChangeEvent cloneWithSource(Object newSource) {
+		return new CollectionChangeEvent(newSource, this.collectionName, this.items);
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source and collection name.
+	 */
+	public CollectionChangeEvent cloneWithSource(Object newSource, String newCollectionName) {
+		return new CollectionChangeEvent(newSource, newCollectionName, this.items);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/ListChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/ListChangeEvent.java
new file mode 100644
index 0000000..d79680f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/ListChangeEvent.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.event;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * A "list change" event gets delivered whenever a model changes a "bound"
+ * or "constrained" list. A ListChangeEvent is sent as an
+ * argument to the ListChangeListener.
+ * 
+ * Normally a ListChangeEvent is accompanied by the list name,
+ * the items that were added to or removed from the changed list,
+ * and the index of where the items are or were in the list.
+ * 
+ * Design options:
+ * - create a list to wrap a single added or removed item
+ * 	(this is the option we implemented below and in collaborating code)
+ * 	since there is no way to optimize downstream code for
+ * 	single items, we take another performance hit by building
+ * 	a list each time  (@see Collections.singletonList(Object))
+ * 	and forcing downstream code to use a list iterator every time
+ * 
+ * - fire a separate event for each item added or removed
+ * 	eliminates any potential for optimizations to downstream code
+ * 
+ * - add protocol to support both single items and collections
+ * 	adds conditional logic to downstream code
+ */
+public class ListChangeEvent extends ChangeEvent {
+
+	/**
+	 * Name of the list that changed.
+	 */
+	private final String listName;
+
+	/**
+	 * The index at which the items were added or removed.
+	 * In the case of "moved" items, this will be the "target" index.
+	 * May be -1, if not known.
+	 */
+	private final int index;
+
+	/**
+	 * The items that were added to or removed from the list. In the case of
+	 * "replaced" items, these are the new items in the list.
+	 * In the case of "moved" items, this will be empty.
+	 * May be empty, if not known.
+	 */
+	private final List<?> items;
+
+	/**
+	 * The items in the list that were replaced by the items listed above,
+	 * in #items. May be empty, if not known.
+	 */
+	private final List<?> replacedItems;
+
+	/**
+	 * In the case of "moved" items, this will be the "source" index.
+	 * May be -1, if not known.
+	 */
+	private final int sourceIndex;
+
+	/**
+	 * In the case of "moved" items, this will be the number of items moved.
+	 * May be -1, if not known.
+	 */
+	private final int moveLength;
+
+	private static final long serialVersionUID = 1L;
+
+
+	protected ListChangeEvent(Object source, String listName, int index, List<?> items, List<?> replacedItems, int sourceIndex, int moveLength) {
+		super(source);
+		if ((listName == null) || (items == null) || (replacedItems == null)) {
+			throw new NullPointerException();
+		}
+		this.listName = listName;
+		this.index = index;
+		this.items = Collections.unmodifiableList(items);
+		this.replacedItems = Collections.unmodifiableList(replacedItems);
+		this.sourceIndex = sourceIndex;
+		this.moveLength = moveLength;
+	}
+	
+	/**
+	 * Construct a new list change event for a list of replaced items.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param listName The programmatic name of the list that was changed.
+	 * @param index The index at which the items in the list were replaced.
+	 * @param items The new items in the list.
+	 * @param replacedItems The items in the list that were replaced.
+	 */
+	public ListChangeEvent(Object source, String listName, int index, List<?> items, List<?> replacedItems) {
+		this(source, listName, index, items, replacedItems, -1, -1);
+	}
+	
+	/**
+	 * Construct a new list change event for a list of added or removed items.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param listName The programmatic name of the list that was changed.
+	 * @param index The index at which the items were added to or removed from the list.
+	 * @param items The items that were added to or removed from the list.
+	 */
+	@SuppressWarnings("unchecked")
+	public ListChangeEvent(Object source, String listName, int index, List<?> items) {
+		this(source, listName, index, items, Collections.emptyList(), -1, -1);
+	}
+	
+	/**
+	 * Construct a new list change event for a list of moved items.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param listName The programmatic name of the list that was changed.
+	 * @param targetIndex The index to which the items were moved.
+	 * @param sourceIndex The index from which the items were moved.
+	 */
+	@SuppressWarnings("unchecked")
+	public ListChangeEvent(Object source, String listName, int targetIndex, int sourceIndex, int length) {
+		this(source, listName, targetIndex, Collections.emptyList(), Collections.emptyList(), sourceIndex, length);
+	}
+	
+	/**
+	 * Construct a new list change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param listName The programmatic name of the list that was changed.
+	 */
+	@SuppressWarnings("unchecked")
+	public ListChangeEvent(Object source, String listName) {
+		this(source, listName, -1, Collections.emptyList(), Collections.emptyList(), -1, -1);
+	}
+	
+	/**
+	 * Return the programmatic name of the list that was changed.
+	 */
+	public String listName() {
+		return this.listName;
+	}
+
+	/**
+	 * Return the index at which the items were added to or removed from the list.
+	 * In the case of "moved" items, this will be the "target" index.
+	 * May be -1 if inappropriate or unknown.
+	 */
+	public int index() {
+		return this.index;
+	}
+
+	/**
+	 * Return the index at which the items were added to or removed from the list.
+	 * In the case of "moved" items, this will be the "target" index.
+	 * May be -1 if inappropriate or unknown.
+	 */
+	public int targetIndex() {
+		return this.index;
+	}
+
+	/**
+	 * Return a list iterator on the items that were added to or
+	 * removed from the list. In the case of "replaced" items, these
+	 * are the new items in the list.
+	 * May be empty if inappropriate or unknown.
+	 */
+	public ListIterator<?> items() {
+		return this.items.listIterator();
+	}
+
+	/**
+	 * Return the number of items that were added to or
+	 * removed from the list.
+	 * May be 0 if inappropriate or unknown.
+	 */
+	public int itemsSize() {
+		return this.items.size();
+	}
+
+	/**
+	 * Return a list iterator on the items in the list that were replaced.
+	 * May be empty if inappropriate or unknown.
+	 */
+	public ListIterator<?> replacedItems() {
+		return this.replacedItems.listIterator();
+	}
+
+	/**
+	 * In the case of "moved" items, this will be the "source" index.
+	 * May be -1 if inappropriate or unknown.
+	 */
+	public int sourceIndex() {
+		return this.sourceIndex;
+	}
+
+	/**
+	 * In the case of "moved" items, this will be the number of items moved.
+	 * May be -1 if inappropriate or unknown.
+	 */
+	public int moveLength() {
+		return this.moveLength;
+	}
+
+	@Override
+	public String aspectName() {
+		return this.listName;
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source.
+	 */
+	@Override
+	public ListChangeEvent cloneWithSource(Object newSource) {
+		return new ListChangeEvent(newSource, this.listName, this.index, this.items, this.replacedItems);
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source and list name.
+	 */
+	public ListChangeEvent cloneWithSource(Object newSource, String newListName) {
+		return new ListChangeEvent(newSource, newListName, this.index, this.items, this.replacedItems);
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source and list name and displacing
+	 * the index by the specified amount.
+	 */
+	public ListChangeEvent cloneWithSource(Object newSource, String newListName, int offset) {
+		return new ListChangeEvent(newSource, newListName, this.index + offset, this.items, this.replacedItems);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/PropertyChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/PropertyChangeEvent.java
new file mode 100644
index 0000000..d78a372
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/PropertyChangeEvent.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.event;
+
+/**
+ * A "property change" event gets delivered whenever a model changes a "bound"
+ * or "constrained" property. A PropertyChangeEvent is sent as an
+ * argument to the PropertyChangeListener.
+ */
+public class PropertyChangeEvent extends ChangeEvent {
+
+	/** Name of the property that changed. */
+	private final String propertyName;
+
+	/** The property's old value, before the change. */
+	private final Object oldValue;
+
+	/** The property's new value, after the change. */
+	private final Object newValue;
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a new property change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param propertyName The programmatic name of the property that was changed.
+	 * @param oldValue The old value of the property.
+	 * @param newValue The new value of the property.
+	 */
+	public PropertyChangeEvent(Object source, String propertyName, Object oldValue, Object newValue) {
+		super(source);
+		if (propertyName == null) {
+			throw new NullPointerException();
+		}
+		this.propertyName = propertyName;
+		this.oldValue = oldValue;
+		this.newValue = newValue;
+	}
+
+	/**
+	 * Return the programmatic name of the property that was changed.
+	 */
+	public String propertyName() {
+		return this.propertyName;
+	}
+
+	/**
+	 * Return the old value of the property.
+	 */
+	public Object oldValue() {
+		return this.oldValue;
+	}
+
+	/**
+	 * Return the new value of the property.
+	 */
+	public Object newValue() {
+		return this.newValue;
+	}
+
+	@Override
+	public String aspectName() {
+		return this.propertyName;
+	}
+
+	@Override
+	public PropertyChangeEvent cloneWithSource(Object newSource) {
+		return new PropertyChangeEvent(newSource, this.propertyName, this.oldValue, this.newValue);
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source and the property name.
+	 */
+	public PropertyChangeEvent cloneWithSource(Object newSource, String newPropertyName) {
+		return new PropertyChangeEvent(newSource, newPropertyName, this.oldValue, this.newValue);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/StateChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/StateChangeEvent.java
new file mode 100644
index 0000000..a73e178
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/StateChangeEvent.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.event;
+
+/**
+ * A generic "state change" event gets delivered whenever a model changes to 
+ * such extent that it cannot be delineated all aspects of it that have changed. 
+ * A StateChangeEvent is sent as an argument to the StateChangeListener.
+ */
+public class StateChangeEvent extends ChangeEvent {
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a new state change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 */
+	public StateChangeEvent(Object source) {
+		super(source);
+	}
+
+	@Override
+	public String aspectName() {
+		return null;  // the point of the event is that the name is unknown...
+	}
+
+	@Override
+	public StateChangeEvent cloneWithSource(Object newSource) {
+		return new StateChangeEvent(newSource);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/TreeChangeEvent.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/TreeChangeEvent.java
new file mode 100644
index 0000000..b42477d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/event/TreeChangeEvent.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.event;
+
+/**
+ * A "tree change" event gets delivered whenever a model changes a "bound"
+ * or "constrained" tree. A TreeChangeEvent is sent as an
+ * argument to the TreeChangeListener.
+ * 
+ * Normally a TreeChangeEvent is accompanied by the tree name and a path
+ * to the part of the tree that was changed.
+ */
+public class TreeChangeEvent extends ChangeEvent {
+
+	/** Name of the tree that changed. */
+	private final String treeName;
+
+    /**
+     * Path to the parent of the part of the tree that was changed.
+     * May be empty, if not known or if the entire tree changed.
+     */
+	protected final Object[] path;
+
+	private static final Object[] EMPTY_PATH = new Object[0];
+
+	private static final long serialVersionUID = 1L;
+
+
+	/**
+	 * Construct a new tree change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param treeName The programmatic name of the tree that was changed.
+	 * @param path The path to the part of the tree that was changed.
+	 */
+	public TreeChangeEvent(Object source, String treeName, Object[] path) {
+		super(source);
+		if ((treeName == null) || (path == null)) {
+			throw new NullPointerException();
+		}
+		this.treeName = treeName;
+		this.path = path;
+	}
+	
+	/**
+	 * Construct a new tree change event.
+	 *
+	 * @param source The object on which the event initially occurred.
+	 * @param treeName The programmatic name of the tree that was changed.
+	 */
+	@SuppressWarnings("unchecked")
+	public TreeChangeEvent(Object source, String treeName) {
+		this(source, treeName, EMPTY_PATH);
+	}
+	
+	/**
+	 * Return the programmatic name of the tree that was changed.
+	 */
+	public String treeName() {
+		return this.treeName;
+	}
+
+	/**
+	 * Return the path to the part of the tree that was changed.
+	 * May be null, if not known.
+	 */
+	public Object[] path() {
+		return this.path;
+	}
+
+	@Override
+	public String aspectName() {
+		return this.treeName;
+	}
+
+	@Override
+	public TreeChangeEvent cloneWithSource(Object newSource) {
+		return new TreeChangeEvent(newSource, this.treeName, this.path);
+	}
+
+	/**
+	 * Return a copy of the event with the specified source
+	 * replacing the current source and the tree name.
+	 */
+	public TreeChangeEvent cloneWithSource(Object newSource, String newTreeName) {
+		return new TreeChangeEvent(newSource, newTreeName, this.path);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ChangeListener.java
new file mode 100644
index 0000000..5224781
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ChangeListener.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import java.util.EventListener;
+
+/**
+ * Marker interface.
+ */
+public interface ChangeListener extends EventListener {
+	// nothing for now
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/CollectionChangeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/CollectionChangeAdapter.java
new file mode 100644
index 0000000..34d2f9d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/CollectionChangeAdapter.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+
+/**
+ * Convenience implementation of CollectionChangeListener.
+ */
+public class CollectionChangeAdapter implements CollectionChangeListener {
+
+	/**
+	 * Default constructor.
+	 */
+	public CollectionChangeAdapter() {
+		super();
+	}
+
+	public void itemsAdded(CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsRemoved(CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void collectionCleared(CollectionChangeEvent event) {
+		// do nothing
+	}
+
+	public void collectionChanged(CollectionChangeEvent event) {
+		// do nothing
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/CollectionChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/CollectionChangeListener.java
new file mode 100644
index 0000000..86009d1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/CollectionChangeListener.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+
+/**
+ * A "collection change" event gets fired whenever a model changes a "bound"
+ * collection. You can register a CollectionChangeListener with a source
+ * model so as to be notified of any bound collection updates.
+ */
+public interface CollectionChangeListener extends ChangeListener {
+
+	/**
+	 * This method gets called when items are added to a bound collection.
+	 * 
+	 * @param event A CollectionChangeEvent describing the event source,
+	 * the collection that changed, and the items that were added.
+	 */
+	void itemsAdded(CollectionChangeEvent event);
+
+	/**
+	 * This method gets called when items are removed from a bound collection.
+	 * 
+	 * @param event A CollectionChangeEvent describing the event source,
+	 * the collection that changed, and the items that were removed.
+	 */
+	void itemsRemoved(CollectionChangeEvent event);
+
+	/**
+	 * This method gets called when a bound collection is cleared.
+	 * 
+	 * @param event A CollectionChangeEvent describing the event source 
+	 * and the collection that changed.
+	 */
+	void collectionCleared(CollectionChangeEvent event);
+
+	/**
+	 * This method gets called when a bound collection is changed in a manner
+	 * that is not easily characterized by the other methods in this interface.
+	 * 
+	 * @param event A CollectionChangeEvent describing the event source 
+	 * and the collection that changed.
+	 */
+	void collectionChanged(CollectionChangeEvent event);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ListChangeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ListChangeAdapter.java
new file mode 100644
index 0000000..5468ac3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ListChangeAdapter.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+
+/**
+ * Convenience implementation of ListChangeListener.
+ */
+public class ListChangeAdapter implements ListChangeListener {
+
+	/**
+	 * Default constructor.
+	 */
+	public ListChangeAdapter() {
+		super();
+	}
+
+	public void itemsAdded(ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsRemoved(ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsReplaced(ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void itemsMoved(ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void listCleared(ListChangeEvent event) {
+		// do nothing
+	}
+
+	public void listChanged(ListChangeEvent event) {
+		// do nothing
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ListChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ListChangeListener.java
new file mode 100644
index 0000000..ad3454b
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ListChangeListener.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+
+/**
+ * A "list change" event gets fired whenever a model changes a "bound"
+ * list. You can register a ListChangeListener with a source
+ * model so as to be notified of any bound list updates.
+ */
+public interface ListChangeListener extends ChangeListener {
+
+	/**
+	 * This method gets called when items are added to a bound list.
+	 * 
+	 * @param event A ListChangeEvent describing the event source,
+	 * the list that changed, the items that were added, and the index
+	 * at which the items were added.
+	 */
+	void itemsAdded(ListChangeEvent event);
+
+	/**
+	 * This method gets called when items are removed from a bound list.
+	 * 
+	 * @param event A ListChangeEvent describing the event source,
+	 * the list that changed, the items that were removed, and the index
+	 * at which the items were removed.
+	 */
+	void itemsRemoved(ListChangeEvent event);
+
+	/**
+	 * This method gets called when items in a bound list are replaced.
+	 * 
+	 * @param event A ListChangeEvent describing the event source,
+	 * the list that changed, the items that were added, the items that were
+	 * replaced, and the index at which the items were replaced.
+	 */
+	void itemsReplaced(ListChangeEvent event);
+
+	/**
+	 * This method gets called when items in a bound list are moved.
+	 * 
+	 * @param event A ListChangeEvent describing the event source,
+	 * the list that changed, and the indices of where items were moved
+	 * from and to.
+	 */
+	void itemsMoved(ListChangeEvent event);
+
+	/**
+	 * This method gets called when a bound list is cleared.
+	 * 
+	 * @param event A ListChangeEvent object describing the event source 
+	 * and the list that changed.
+	 */
+	void listCleared(ListChangeEvent event);
+
+	/**
+	 * This method gets called when a bound list is changed in a manner
+	 * that is not easily characterized by the other methods in this interface.
+	 * 
+	 * @param event A ListChangeEvent object describing the event source 
+	 * and the list that changed.
+	 */
+	void listChanged(ListChangeEvent event);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/MultiMethodReflectiveChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/MultiMethodReflectiveChangeListener.java
new file mode 100644
index 0000000..ddc89fe
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/MultiMethodReflectiveChangeListener.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+
+/**
+ * This class is used by ReflectiveChangeListener when the requested listener
+ * needs to implement multiple methods (i.e. CollectionChangeListener,
+ * ListChangeListener, or TreeChangeListener).
+ */
+class MultiMethodReflectiveChangeListener
+	extends ReflectiveChangeListener 
+	implements CollectionChangeListener, ListChangeListener, TreeChangeListener
+{
+	/** the methods we will invoke on the target object */
+	private final Method addMethod;
+	private final Method removeMethod;
+	private final Method replaceMethod;	// this can be null
+	private final Method moveMethod;	// this can be null
+	private final Method clearMethod;
+	private final Method changeMethod;
+
+
+	/**
+	 * The "replace" and "move" methods are optional.
+	 */
+	MultiMethodReflectiveChangeListener(Object target, Method addMethod, Method removeMethod, Method replaceMethod, Method moveMethod, Method clearMethod, Method changeMethod) {
+		super(target);
+		this.addMethod = addMethod;
+		this.removeMethod = removeMethod;
+		this.replaceMethod = replaceMethod;
+		this.moveMethod = moveMethod;
+		this.clearMethod = clearMethod;
+		this.changeMethod = changeMethod;
+	}
+
+	/**
+	 * No "replace" or "move" methods.
+	 */
+	MultiMethodReflectiveChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) {
+		this(target, addMethod, removeMethod, null, null, clearMethod, changeMethod);
+	}
+
+
+	// ********** CollectionChangeListener implementation **********
+
+	private void invoke(Method method, CollectionChangeEvent event) {
+		if (method.getParameterTypes().length == 0) {
+			ClassTools.executeMethod(method, this.target, EMPTY_COLLECTION_CHANGE_EVENT_ARRAY);
+		} else {
+			ClassTools.executeMethod(method, this.target, new CollectionChangeEvent[] {event});
+		}
+	}
+
+	public void itemsAdded(CollectionChangeEvent event) {
+		this.invoke(this.addMethod, event);
+	}
+
+	public void itemsRemoved(CollectionChangeEvent event) {
+		this.invoke(this.removeMethod, event);
+	}
+
+	public void collectionCleared(CollectionChangeEvent event) {
+		this.invoke(this.clearMethod, event);
+	}
+
+	public void collectionChanged(CollectionChangeEvent event) {
+		this.invoke(this.changeMethod, event);
+	}
+
+
+	// ********** ListChangeListener implementation **********
+
+	private void invoke(Method method, ListChangeEvent event) {
+		if (method.getParameterTypes().length == 0) {
+			ClassTools.executeMethod(method, this.target, EMPTY_LIST_CHANGE_EVENT_ARRAY);
+		} else {
+			ClassTools.executeMethod(method, this.target, new ListChangeEvent[] {event});
+		}
+	}
+
+	public void itemsAdded(ListChangeEvent event) {
+		this.invoke(this.addMethod, event);
+	}
+
+	public void itemsRemoved(ListChangeEvent event) {
+		this.invoke(this.removeMethod, event);
+	}
+
+	public void itemsReplaced(ListChangeEvent event) {
+		this.invoke(this.replaceMethod, event);
+	}
+
+	public void itemsMoved(ListChangeEvent event) {
+		this.invoke(this.moveMethod, event);
+	}
+
+	public void listCleared(ListChangeEvent event) {
+		this.invoke(this.clearMethod, event);
+	}
+
+	public void listChanged(ListChangeEvent event) {
+		this.invoke(this.changeMethod, event);
+	}
+
+
+	// ********** TreeChangeListener implementation **********
+
+	private void invoke(Method method, TreeChangeEvent event) {
+		if (method.getParameterTypes().length == 0) {
+			ClassTools.executeMethod(method, this.target, EMPTY_TREE_CHANGE_EVENT_ARRAY);
+		} else {
+			ClassTools.executeMethod(method, this.target, new TreeChangeEvent[] {event});
+		}
+	}
+
+	public void nodeAdded(TreeChangeEvent event) {
+		this.invoke(this.addMethod, event);
+	}
+
+	public void nodeRemoved(TreeChangeEvent event) {
+		this.invoke(this.removeMethod, event);
+	}
+
+	public void treeCleared(TreeChangeEvent event) {
+		this.invoke(this.clearMethod, event);
+	}
+
+	public void treeChanged(TreeChangeEvent event) {
+		this.invoke(this.changeMethod, event);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/PropertyChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/PropertyChangeListener.java
new file mode 100644
index 0000000..bd0d453
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/PropertyChangeListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+
+/**
+ * A "property change" event gets fired whenever a model changes a "bound"
+ * property. You can register a PropertyChangeListener with a source
+ * model so as to be notified of any bound property updates.
+ */
+public interface PropertyChangeListener extends ChangeListener {
+
+	/**
+	 * This method gets called when a model has changed a bound property.
+	 * 
+	 * @param event A StateChangeEvent describing the event source
+	 * and the property's old and new values.
+	 */
+	void propertyChanged(PropertyChangeEvent event);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ReflectiveChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ReflectiveChangeListener.java
new file mode 100644
index 0000000..7a1e074
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/ReflectiveChangeListener.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.event.ChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+
+/**
+ * This factory builds listeners that reflectively forward ChangeEvents.
+ * If you are worried about having too many little classes that have to be
+ * loaded and maintained by the class loader, you can use one of these.
+ * Of course, this comes with the additional overhead of reflection....
+ * Also note that the validity of the method name is not checked at compile
+ * time, but at runtime; although we *do* check the method as soon as the
+ * listener is instantiated.
+ */
+public abstract class ReflectiveChangeListener {
+
+	/** the target object on which we will invoke the method */
+	protected final Object target;
+
+
+	protected static final Class<StateChangeEvent> STATE_CHANGE_EVENT_CLASS = StateChangeEvent.class;
+	@SuppressWarnings("unchecked")
+	protected static final Class<StateChangeEvent>[] STATE_CHANGE_EVENT_CLASS_ARRAY = new Class[] {STATE_CHANGE_EVENT_CLASS};
+	protected static final StateChangeEvent[] EMPTY_STATE_CHANGE_EVENT_ARRAY = new StateChangeEvent[0];
+
+	protected static final Class<PropertyChangeEvent> PROPERTY_CHANGE_EVENT_CLASS = PropertyChangeEvent.class;
+	@SuppressWarnings("unchecked")
+	protected static final Class<PropertyChangeEvent>[] PROPERTY_CHANGE_EVENT_CLASS_ARRAY = new Class[] {PROPERTY_CHANGE_EVENT_CLASS};
+	protected static final PropertyChangeEvent[] EMPTY_PROPERTY_CHANGE_EVENT_ARRAY = new PropertyChangeEvent[0];
+
+	protected static final Class<CollectionChangeEvent> COLLECTION_CHANGE_EVENT_CLASS = CollectionChangeEvent.class;
+	@SuppressWarnings("unchecked")
+	protected static final Class<CollectionChangeEvent>[] COLLECTION_CHANGE_EVENT_CLASS_ARRAY = new Class[] {COLLECTION_CHANGE_EVENT_CLASS};
+	protected static final CollectionChangeEvent[] EMPTY_COLLECTION_CHANGE_EVENT_ARRAY = new CollectionChangeEvent[0];
+
+	protected static final Class<ListChangeEvent> LIST_CHANGE_EVENT_CLASS = ListChangeEvent.class;
+	@SuppressWarnings("unchecked")
+	protected static final Class<ListChangeEvent>[] LIST_CHANGE_EVENT_CLASS_ARRAY = new Class[] {LIST_CHANGE_EVENT_CLASS};
+	protected static final ListChangeEvent[] EMPTY_LIST_CHANGE_EVENT_ARRAY = new ListChangeEvent[0];
+
+	protected static final Class<TreeChangeEvent> TREE_CHANGE_EVENT_CLASS = TreeChangeEvent.class;
+	@SuppressWarnings("unchecked")
+	protected static final Class<TreeChangeEvent>[] TREE_CHANGE_EVENT_CLASS_ARRAY = new Class[] {TREE_CHANGE_EVENT_CLASS};
+	protected static final TreeChangeEvent[] EMPTY_TREE_CHANGE_EVENT_ARRAY = new TreeChangeEvent[0];
+
+
+
+	// ********** helper methods **********
+
+	/**
+	 * Find and return a method implemented by the target that can be invoked
+	 * reflectively when a change event occurs.
+	 */
+	private static Method findChangeListenerMethod(Object target, String methodName, Class<? extends ChangeEvent>[] eventClassArray) {
+		Method method;
+		try {
+			method = ClassTools.method(target, methodName, eventClassArray);
+		} catch (NoSuchMethodException ex1) {
+			try {
+				method = ClassTools.method(target, methodName);
+			} catch (NoSuchMethodException ex2) {
+				throw new RuntimeException(ex2);  // "checked" exceptions bite
+			}
+		}
+		return method;
+	}
+
+	/**
+	 * Check whether the specified method is suitable for being invoked when a
+	 * change event has occurred. Throw an exception if it is not suitable.
+	 */
+	private static void checkChangeListenerMethod(Method method, Class<? extends ChangeEvent> eventClass) {
+		Class<?>[] parmTypes = method.getParameterTypes();
+		int parmTypesLength = parmTypes.length;
+		if (parmTypesLength == 0) {
+			return;
+		}
+		if ((parmTypesLength == 1) && parmTypes[0].isAssignableFrom(eventClass)) {
+			return;
+		}
+		throw new IllegalArgumentException(method.toString());
+	}
+
+
+	// ********** factory methods: StateChangeListener **********
+
+	/**
+	 * Construct a state change listener that will invoke the specified method
+	 * on the specified target.
+	 */
+	public static StateChangeListener buildStateChangeListener(Object target, Method method) {
+		checkChangeListenerMethod(method, STATE_CHANGE_EVENT_CLASS);
+		return new SingleMethodReflectiveChangeListener(target, method);
+	}
+
+	/**
+	 * Construct a state change listener that will invoke the specified method
+	 * on the specified target. If a single-argument method with the specified
+	 * name and appropriate argument is found, it will be invoked; otherwise,
+	 * a zero-argument method with the specified name will be invoked.
+	 */
+	public static StateChangeListener buildStateChangeListener(Object target, String methodName) {
+		return buildStateChangeListener(target, findChangeListenerMethod(target, methodName, STATE_CHANGE_EVENT_CLASS_ARRAY));
+	}
+
+
+	// ********** factory methods: PropertyChangeListener **********
+
+	/**
+	 * Construct a property change listener that will invoke the specified method
+	 * on the specified target.
+	 */
+	public static PropertyChangeListener buildPropertyChangeListener(Object target, Method method) {
+		checkChangeListenerMethod(method, PROPERTY_CHANGE_EVENT_CLASS);
+		return new SingleMethodReflectiveChangeListener(target, method);
+	}
+
+	/**
+	 * Construct a property change listener that will invoke the specified method
+	 * on the specified target. If a single-argument method with the specified
+	 * name and appropriate argument is found, it will be invoked; otherwise,
+	 * a zero-argument method with the specified name will be invoked.
+	 */
+	public static PropertyChangeListener buildPropertyChangeListener(Object target, String methodName) {
+		return buildPropertyChangeListener(target, findChangeListenerMethod(target, methodName, PROPERTY_CHANGE_EVENT_CLASS_ARRAY));
+	}
+
+
+	// ********** factory methods: CollectionChangeListener **********
+
+	/**
+	 * Construct a collection change listener that will invoke the specified methods
+	 * on the specified target.
+	 */
+	public static CollectionChangeListener buildCollectionChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) {
+		checkChangeListenerMethod(addMethod, COLLECTION_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(removeMethod, COLLECTION_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(clearMethod, COLLECTION_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(changeMethod, COLLECTION_CHANGE_EVENT_CLASS);
+		return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, clearMethod, changeMethod);
+	}
+
+	/**
+	 * Construct a collection change listener that will invoke the specified method
+	 * on the specified target for any change event.
+	 */
+	public static CollectionChangeListener buildCollectionChangeListener(Object target, Method method) {
+		return buildCollectionChangeListener(target, method, method, method, method);
+	}
+
+	/**
+	 * Construct a collection change listener that will invoke the specified methods
+	 * on the specified target for change events. If a single-argument method
+	 * with the specified name and appropriate argument is found, it will be invoked;
+	 * otherwise, a zero-argument method with the specified name will be invoked.
+	 */
+	public static CollectionChangeListener buildCollectionChangeListener(Object target, String addMethodName, String removeMethodName, String clearMethodName, String changeMethodName) {
+		return buildCollectionChangeListener(
+				target,
+				findChangeListenerMethod(target, addMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, removeMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, clearMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, changeMethodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY)
+		);
+	}
+
+	/**
+	 * Construct a collection change listener that will invoke the specified method
+	 * on the specified target for any change event. If a single-argument method
+	 * with the specified name and appropriate argument is found, it will be invoked;
+	 * otherwise, a zero-argument method with the specified name will be invoked.
+	 */
+	public static CollectionChangeListener buildCollectionChangeListener(Object target, String methodName) {
+		return buildCollectionChangeListener(target, findChangeListenerMethod(target, methodName, COLLECTION_CHANGE_EVENT_CLASS_ARRAY));
+	}
+
+
+	// ********** factory methods: ListChangeListener **********
+
+	/**
+	 * Construct a list change listener that will invoke the specified methods
+	 * on the specified target.
+	 */
+	public static ListChangeListener buildListChangeListener(Object target, Method addMethod, Method removeMethod, Method replaceMethod, Method moveMethod, Method clearMethod, Method changeMethod) {
+		checkChangeListenerMethod(addMethod, LIST_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(removeMethod, LIST_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(replaceMethod, LIST_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(moveMethod, LIST_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(clearMethod, LIST_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(changeMethod, LIST_CHANGE_EVENT_CLASS);
+		return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, replaceMethod, moveMethod, clearMethod, changeMethod);
+	}
+
+	/**
+	 * Construct a list change listener that will invoke the specified method
+	 * on the specified target for any change event.
+	 */
+	public static ListChangeListener buildListChangeListener(Object target, Method method) {
+		return buildListChangeListener(target, method, method, method, method, method, method);
+	}
+
+	/**
+	 * Construct a list change listener that will invoke the specified methods
+	 * on the specified target for change events. If a single-argument method
+	 * with the specified name and appropriate argument is found, it will be invoked;
+	 * otherwise, a zero-argument method with the specified name will be invoked.
+	 */
+	public static ListChangeListener buildListChangeListener(Object target, String addMethodName, String removeMethodName, String replaceMethodName, String moveMethodName, String clearMethodName, String changeMethodName) {
+		return buildListChangeListener(
+				target,
+				findChangeListenerMethod(target, addMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, removeMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, replaceMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, moveMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, clearMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, changeMethodName, LIST_CHANGE_EVENT_CLASS_ARRAY)
+		);
+	}
+
+	/**
+	 * Construct a list change listener that will invoke the specified method
+	 * on the specified target for any change event. If a single-argument method
+	 * with the specified name and appropriate argument is found, it will be invoked;
+	 * otherwise, a zero-argument method with the specified name will be invoked.
+	 */
+	public static ListChangeListener buildListChangeListener(Object target, String methodName) {
+		return buildListChangeListener(target, findChangeListenerMethod(target, methodName, LIST_CHANGE_EVENT_CLASS_ARRAY));
+	}
+
+
+	// ********** factory methods: TreeChangeListener **********
+
+	/**
+	 * Construct a tree change listener that will invoke the specified methods
+	 * on the specified target.
+	 */
+	public static TreeChangeListener buildTreeChangeListener(Object target, Method addMethod, Method removeMethod, Method clearMethod, Method changeMethod) {
+		checkChangeListenerMethod(addMethod, TREE_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(removeMethod, TREE_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(clearMethod, TREE_CHANGE_EVENT_CLASS);
+		checkChangeListenerMethod(changeMethod, TREE_CHANGE_EVENT_CLASS);
+		return new MultiMethodReflectiveChangeListener(target, addMethod, removeMethod, clearMethod, changeMethod);
+	}
+
+	/**
+	 * Construct a tree change listener that will invoke the specified method
+	 * on the specified target for any change event.
+	 */
+	public static TreeChangeListener buildTreeChangeListener(Object target, Method method) {
+		return buildTreeChangeListener(target, method, method, method, method);
+	}
+
+	/**
+	 * Construct a tree change listener that will invoke the specified methods
+	 * on the specified target for change events. If a single-argument method
+	 * with the specified name and appropriate argument is found, it will be invoked;
+	 * otherwise, a zero-argument method with the specified name will be invoked.
+	 */
+	public static TreeChangeListener buildTreeChangeListener(Object target, String addMethodName, String removeMethodName, String clearMethodName, String changeMethodName) {
+		return buildTreeChangeListener(
+				target,
+				findChangeListenerMethod(target, addMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, removeMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, clearMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY),
+				findChangeListenerMethod(target, changeMethodName, TREE_CHANGE_EVENT_CLASS_ARRAY)
+		);
+	}
+
+	/**
+	 * Construct a tree change listener that will invoke the specified method
+	 * on the specified target for any change event. If a single-argument method
+	 * with the specified name and appropriate argument is found, it will be invoked;
+	 * otherwise, a zero-argument method with the specified name will be invoked.
+	 */
+	public static TreeChangeListener buildTreeChangeListener(Object target, String methodName) {
+		return buildTreeChangeListener(target, findChangeListenerMethod(target, methodName, TREE_CHANGE_EVENT_CLASS_ARRAY));
+	}
+
+
+	// ********** constructor **********
+
+	/**
+	 * Construct a listener that will invoke the specified method
+	 * on the specified target.
+	 */
+	protected ReflectiveChangeListener(Object target) {
+		super();
+		this.target = target;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/SingleMethodReflectiveChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/SingleMethodReflectiveChangeListener.java
new file mode 100644
index 0000000..9602b84
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/SingleMethodReflectiveChangeListener.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+
+/**
+ * This class is used by ReflectiveChangeListener when the requested listener
+ * need only implement a single method (i.e. StateChangeListener or
+ * PropertyChangeListener).
+ */
+class SingleMethodReflectiveChangeListener
+	extends ReflectiveChangeListener
+	implements StateChangeListener, PropertyChangeListener
+{
+
+	/** the method we will invoke on the target object */
+	private final Method method;
+	/** cache the number of arguments */
+	private final boolean methodIsZeroArgument;
+
+	SingleMethodReflectiveChangeListener(Object target, Method method) {
+		super(target);
+		this.method = method;
+		this.methodIsZeroArgument = method.getParameterTypes().length == 0;
+	}
+
+
+	// ********** StateChangeListener implementation **********
+
+	public void stateChanged(StateChangeEvent event) {
+		if (this.methodIsZeroArgument) {
+			ClassTools.executeMethod(this.method, this.target, EMPTY_STATE_CHANGE_EVENT_ARRAY);
+		} else {
+			ClassTools.executeMethod(this.method, this.target, new StateChangeEvent[] {event});
+		}
+	}
+
+
+	// ********** PropertyChangeListener implementation **********
+
+	public void propertyChanged(PropertyChangeEvent event) {
+		if (this.methodIsZeroArgument) {
+			ClassTools.executeMethod(this.method, this.target, EMPTY_PROPERTY_CHANGE_EVENT_ARRAY);
+		} else {
+			ClassTools.executeMethod(this.method, this.target, new PropertyChangeEvent[] {event});
+		}
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/StateChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/StateChangeListener.java
new file mode 100644
index 0000000..760b209
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/StateChangeListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+
+/**
+ * A generic "state change" event gets delivered whenever a model changes to 
+ * such extent that it cannot be delineated all aspects of it that have changed. 
+ * You can register a StateChangeListener with a source model so as to be notified 
+ * of any such changes.
+ */
+public interface StateChangeListener extends ChangeListener {
+
+	/**
+	 * This method gets called when a model has changed in some general fashion.
+	 * 
+	 * @param event A StateChangeEvent describing the event source.
+	 */
+	void stateChanged(StateChangeEvent event);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/TreeChangeAdapter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/TreeChangeAdapter.java
new file mode 100644
index 0000000..897f4f8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/TreeChangeAdapter.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+
+/**
+ * Convenience implementation of TreeChangeListener.
+ */
+public class TreeChangeAdapter implements TreeChangeListener {
+
+	/**
+	 * Default constructor.
+	 */
+	public TreeChangeAdapter() {
+		super();
+	}
+
+	public void nodeAdded(TreeChangeEvent event) {
+		// do nothing
+	}
+
+	public void nodeRemoved(TreeChangeEvent event) {
+		// do nothing
+	}
+
+	public void treeCleared(TreeChangeEvent event) {
+		// do nothing
+	}
+
+	public void treeChanged(TreeChangeEvent event) {
+		// do nothing
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/TreeChangeListener.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/TreeChangeListener.java
new file mode 100644
index 0000000..b0c87ca
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/listener/TreeChangeListener.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+
+/**
+ * A "tree change" event gets fired whenever a model changes a "bound"
+ * tree. You can register a TreeChangeListener with a source
+ * model so as to be notified of any bound tree updates.
+ */
+public interface TreeChangeListener extends ChangeListener {
+
+	/**
+	 * This method gets called when a node is added to a bound tree.
+	 * 
+	 * @param event A TreeChangeEvent describing the event source,
+	 * the tree that changed, and the path to the node that was added.
+	 */
+	void nodeAdded(TreeChangeEvent event);
+
+	/**
+	 * This method gets called when a node is removed from a bound tree.
+	 * 
+	 * @param event A TreeChangeEvent describing the event source,
+	 * the tree that changed, and the path to the node that was removed.
+	 */
+	void nodeRemoved(TreeChangeEvent event);
+
+	/**
+	 * This method gets called when a bound tree is cleared.
+	 * 
+	 * @param event A TreeChangeEvent describing the event source,
+	 * the tree that changed, and an empty path.
+	 */
+	void treeCleared(TreeChangeEvent event);
+
+	/**
+	 * This method gets called when a portion of a bound tree is changed in
+	 * a manner that is not easily characterized by the other methods in this
+	 * interface.
+	 * 
+	 * @param event A TreeChangeEvent describing the event source,
+	 * the tree that changed, and the path to the branch of the
+	 * tree that changed.
+	 */
+	void treeChanged(TreeChangeEvent event);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AbstractNodeModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AbstractNodeModel.java
new file mode 100644
index 0000000..2f90588
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AbstractNodeModel.java
@@ -0,0 +1,998 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
+import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.ChangeEventDispatcher;
+import org.eclipse.jpt.utility.internal.model.ChangeSupport;
+
+/**
+ * Base class for Node Model classes.
+ * Provides support for the following:
+ *     initialization
+ *     enforced object identity wrt #equals()/#hashCode()
+ *     containment hierarchy (parent/child)
+ *     user comment
+ *     dirty flag
+ *     problems
+ *     sorting
+ * 
+ * Typically, subclasses should consider implementing the following methods:
+ *     the appropriate constructors
+ *         (with the appropriately-restrictive type declaration for parent)
+ *     #initialize()
+ *     #initialize(Node parentNode)
+ *     #checkParent(Node parentNode)
+ *     #addChildrenTo(List list)
+ *     #nodeRemoved(Node)
+ *     #validator()
+ *     #transientAspectNames() or
+ *         #addTransientAspectNamesTo(Set transientAspectNames)
+ *     #addProblemsTo(List currentProblems)
+ *     #nonValidatedAspectNames()
+ *         #addNonValidatedAspectNamesTo(Set nonValidatedAspectNames)
+ *     #displayString()
+ *     #toString(StringBuffer sb)
+ */
+public abstract class AbstractNodeModel 
+	extends AbstractModel 
+	implements NodeModel 
+{
+
+	/** Containment hierarchy. */
+	private volatile Node parent;
+
+	/** User comment. */
+	private volatile String comment;
+		public static final String COMMENT_PROPERTY = "comment";
+
+	/** Track whether the node has changed. */
+	private volatile boolean dirty;
+	private volatile boolean dirtyBranch;
+
+	/**
+	 * The node's problems, as calculated during validation.
+	 * This list should only be modified via a ProblemSynchronizer,
+	 * allowing for asynchronous modification from another thread.
+	 */
+	private List<Problem> problems;		// pseudo-final
+		private static final Object[] EMPTY_PROBLEM_MESSAGE_ARGUMENTS = new Object[0];
+
+	/**
+	 * Cache the node's "branch" problems, as calculated during validation.
+	 * This list should only be modified via a ProblemSynchronizer,
+	 * allowing for asynchronous modification from another thread.
+	 * This must be recalculated every time this node or one of its
+	 * descendants changes it problems.
+	 */
+	private List<Problem> branchProblems;		// pseudo-final
+
+
+
+	/**
+	 * Sets of transient aspect names, keyed by class.
+	 * This is built up lazily, as the objects are modified.
+	 */
+	private static final Map<Class<? extends AbstractNodeModel>, Set<String>> transientAspectNameSets = new Hashtable<Class<? extends AbstractNodeModel>, Set<String>>();
+
+	/**
+	 * Sets of non-validated aspect names, keyed by class.
+	 * This is built up lazily, as the objects are modified.
+	 */
+	private static final Map<Class<? extends AbstractNodeModel>, Set<String>> nonValidatedAspectNameSets = new Hashtable<Class<? extends AbstractNodeModel>, Set<String>>();
+
+
+	// ********** constructors **********
+
+	/**
+	 * Most objects must have a parent.
+	 * Use this constructor to create a new node.
+	 * @see #initialize(Node)
+	 */
+	protected AbstractNodeModel(Node parent) {
+		super();
+		this.initialize(parent);
+	}
+
+
+	// ********** initialization **********
+
+	/**
+	 * Initialize a newly-created instance.
+	 * @see #initialize(Node)
+	 */
+	@Override
+	protected void initialize() {
+		super.initialize();
+		this.comment = "";
+
+		// a new object is dirty, by definition
+		this.dirty = true;
+		this.dirtyBranch = true;
+
+		this.problems = new Vector<Problem>();
+		this.branchProblems = new Vector<Problem>();
+
+	// when you override this method, don't forget to include:
+	//	super.initialize();
+	}
+
+	/**
+	 * Initialize a newly-created instance.
+	 * @see #initialize()
+	 */
+	protected void initialize(Node parentNode) {
+		this.checkParent(parentNode);
+		this.parent = parentNode;
+	// when you override this method, don't forget to include:
+	//	super.initialize(parentNode);
+	}
+
+	/**
+	 * Build a change support object that will notify the node
+	 * when one of the node's aspects has changed.
+	 * @see #aspectChanged(String)
+	 */
+	@Override
+	protected ChangeSupport buildChangeSupport() {
+		return new ChangeSupport(this) {
+			private static final long serialVersionUID = 1L;
+			@Override
+			protected ChangeEventDispatcher dispatcher() {
+				return AbstractNodeModel.this.changeEventDispatcher();
+			}
+			@Override
+			protected ChangeSupport buildChildChangeSupport() {
+				return AbstractNodeModel.this.buildChildChangeSupport();
+			}
+			@Override
+			protected void sourceChanged(String aspectName) {
+				super.sourceChanged(aspectName);
+				AbstractNodeModel.this.aspectChanged(aspectName);
+			}
+		};
+	}
+
+	/**
+	 * The aspect-specific change support objects do not need to
+	 * notify the node of changes (the parent will take care of that);
+	 * nor do they need to build "grandchildren" change support objects.
+	 */
+	protected ChangeSupport buildChildChangeSupport() {
+		return new ChangeSupport(this) {
+			private static final long serialVersionUID = 1L;
+			@Override
+			protected ChangeEventDispatcher dispatcher() {
+				return AbstractNodeModel.this.changeEventDispatcher();
+			}
+			@Override
+			protected ChangeSupport buildChildChangeSupport() {
+				// there are no grandchildren
+				throw new UnsupportedOperationException();
+			}
+		};
+	}
+
+
+	// ********** equality **********
+
+	/**
+	 * Enforce object identity - do not allow objects to be equal unless
+	 * they are the same object.
+	 * Do NOT override this method - we rely on object identity extensively.
+	 */
+	@Override
+	public final boolean equals(Object o) {
+		return this == o;
+	}
+
+	/**
+	 * Enforce object identity - do not allow objects to be equal unless
+	 * they are the same object.
+	 * Do NOT override this method - we rely on object identity extensively.
+	 */
+	@Override
+	public final int hashCode() {
+		return super.hashCode();
+	}
+
+
+	// ********** containment hierarchy (parent/children) **********
+
+	/**
+	 * INTRA-TREE API?
+	 * Return the node's parent in the containment hierarchy.
+	 * Most nodes must have a parent.
+	 */
+	public final Node parent() {
+		return this.parent;
+	}
+
+	/**
+	 * Throw an IllegalArgumentException if the parent is not valid
+	 * for the node.
+	 * By default require a non-null parent. Override if other restrictions exist
+	 * or the parent should be null.
+	 */
+	protected void checkParent(Node parentNode) {
+		if (parentNode == null) {
+			throw new IllegalArgumentException("The parent node cannot be null");
+		}
+	}
+
+	/**
+	 * INTRA-TREE API?
+	 * Return the node's children, which are also nodes.
+	 * Do NOT override this method.
+	 * Override #addChildrenTo(List).
+	 * @see #addChildrenTo(java.util.List)
+	 */
+	public final Iterator<Node> children() {
+		List<Node> children = new ArrayList<Node>();
+		this.addChildrenTo(children);
+		return children.iterator();
+	}
+
+	/**
+	 * Subclasses should override this method to add their children
+	 * to the specified list.
+	 * @see #children()
+	 */
+	protected void addChildrenTo(List<Node> list) {
+		// this class has no children, subclasses will...
+	// when you override this method, don't forget to include:
+	//	super.addChildrenTo(list);
+	}
+
+	/**
+	 * Return whether the node is a descendant of the specified node.
+	 * By definition, a node is a descendant of itself.
+	 */
+	public final boolean isDescendantOf(Node node) {
+		return (this == node) || this.parentIsDescendantOf(node);
+	}
+
+	protected boolean parentIsDescendantOf(Node node) {
+		return (this.parent != null) && this.parent.isDescendantOf(node);
+	}
+
+	/**
+	 * Return a collection holding all the node's "references", and all
+	 * the node's descendants' "references". "References" are
+	 * objects that are "referenced" by another object, as opposed
+	 * to "owned" by another object.
+	 */
+	public final Iterator<Node> branchReferences() {
+		Collection<Node> branchReferences = new ArrayList<Node>(1000);		// start big
+		this.addBranchReferencesTo(branchReferences);
+		return branchReferences.iterator();
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Add the node's "references", and all the node's descendants'
+	 * "references", to the specified collection. "References" are
+	 * objects that are "referenced" by another object, as opposed
+	 * to "owned" by another object.
+	 * This method is of particular concern to Handles, since most
+	 * (hopefully all) "references" are held by Handles.
+	 * @see Reference
+	 * @see #children()
+	 */
+	public final void addBranchReferencesTo(Collection<Node> branchReferences) {
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.addBranchReferencesTo(branchReferences);
+		}
+	}
+
+	/**
+	 * Return all the nodes in the object's branch of the tree,
+	 * including the node itself. The nodes will probably returned
+	 * in "depth-first" order.
+	 * Only really used for testing and debugging.
+	 */
+	public final Iterator<Node> allNodes() {
+		Collection<Node> nodes = new ArrayList<Node>(1000);		// start big
+		this.addAllNodesTo(nodes);
+		return nodes.iterator();
+	}
+
+	/**
+	 * INTRA-TREE API?
+	 * Add all the nodes in the object's branch of the tree,
+	 * including the node itself, to the specified collection.
+	 * Only really used for testing and debugging.
+	 */
+	public final void addAllNodesTo(Collection<Node> nodes) {
+		nodes.add(this);
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.addAllNodesTo(nodes);
+		}
+	}
+
+
+	// ********** model synchronization support **********
+
+	/**
+	 * INTRA-TREE API
+	 * This is a general notification that the specified node has been
+	 * removed from the tree. The node receiving this notification
+	 * should perform any necessary updates to remain in synch
+	 * with the tree (e.g. clearing out or replacing any references
+	 * to the removed node or any of the removed node's descendants).
+	 * @see #isDescendantOf(Node)
+	 */
+	public void nodeRemoved(Node node) {
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.nodeRemoved(node);
+		}
+	// when you override this method, don't forget to include:
+	//	super.nodeRemoved(node);
+	}
+
+	/**
+	 * convenience method
+	 * return whether node1 is a descendant of node2;
+	 * node1 can be null
+	 */
+	protected boolean nodeIsDescendantOf(Node node1, Node node2) {
+		return (node1 != null) && node1.isDescendantOf(node2);
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * This is a general notification that the specified node has been
+	 * renamed. The node receiving this notification should mark its
+	 * branch dirty if necessary (i.e. it references the renamed node
+	 * or one of its descendants). This method is of particular concern
+	 * to Handles.
+	 * @see #isDescendantOf(Node)
+	 */
+	public void nodeRenamed(Node node) {
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.nodeRenamed(node);
+		}
+	// when you override this method, don't forget to include:
+	//	super.nodeRenamed(node);
+	}
+	
+	
+	// ********** user comment **********
+
+	/**
+	 * Return the object's user comment.
+	 */
+	public final String comment() {
+		return this.comment;
+	}
+
+	/**
+	 * Set the object's user comment.
+	 */
+	public final void setComment(String comment) {
+		Object old = this.comment;
+		this.comment = comment;
+		this.firePropertyChanged(COMMENT_PROPERTY, old, comment);
+	}
+
+
+	// ********** change support **********
+
+	/**
+	 * INTRA-TREE API
+	 * Return a change event dispatcher that will be used to dispatch
+	 * change notifications to listeners.
+	 * Typically only the root node directly holds a dispatcher.
+	 */
+	public ChangeEventDispatcher changeEventDispatcher() {
+		if (this.parent == null) {
+			throw new IllegalStateException("This node should not be firing change events during its construction.");
+		}
+		return this.parent.changeEventDispatcher();
+	}
+
+	/**
+	 * Set a change event dispatcher that will be used to dispatch
+	 * change notifications to listeners.
+	 * Typically only the root node directly holds a dispatcher.
+	 */
+	public void setChangeEventDispatcher(ChangeEventDispatcher changeEventDispatcher) {
+		if (this.parent == null) {
+			throw new IllegalStateException("This root node should implement #setChangeEventDispatcher(ChangeEventDispatcher).");
+		}
+		throw new UnsupportedOperationException("Only root nodes implement #setChangeEventDispatcher(ChangeEventDispatcher).");
+	}
+
+	/**
+	 * An aspect of the node has changed:
+	 * 	- if it is a persistent aspect, mark the object dirty
+	 * 	- if it is a significant aspect, validate the object
+	 */
+	protected void aspectChanged(String aspectName) {
+		if (this.aspectIsPersistent(aspectName)) {
+			// System.out.println(Thread.currentThread() + " dirty change: " + this + ": " + aspectName);
+			this.markDirty();
+		}
+		if (this.aspectChangeRequiresValidation(aspectName)) {
+			// System.out.println(Thread.currentThread() + " validation change: " + this + ": " + aspectName);
+			this.validator().validate();
+		}
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Return a validator that will be invoked whenever a
+	 * "validated" aspect of the node tree changes.
+	 * Typically only the root node directly holds a validator.
+	 */
+	public Node.Validator validator() {
+		if (this.parent == null) {
+			throw new IllegalStateException("This node should not be firing change events during its construction.");
+		}
+		return this.parent.validator();
+	}
+
+	/**
+	 * Set a validator that will be invoked whenever a
+	 * "validated" aspect of the node tree changes.
+	 * Typically only the root node directly holds a validator.
+	 */
+	public void setValidator(Node.Validator validator) {
+		if (this.parent == null) {
+			throw new IllegalStateException("This root node should implement #setValidator(Node.Validator).");
+		}
+		throw new UnsupportedOperationException("Only root nodes implement #setValidator(Node.Validator).");
+	}
+
+
+	// ********** dirty flag support **********
+
+	/**
+	 * Return whether any persistent aspects of the object
+	 * have changed since the object was last read or saved.
+	 * This does NOT include changes to the object's descendants.
+	 */
+	public final boolean isDirty() {
+		return this.dirty;
+	}
+
+	/**
+	 * Return whether any persistent aspects of the object,
+	 * or any of its descendants, have changed since the object and
+	 * its descendants were last read or saved.
+	 */
+	public final boolean isDirtyBranch() {
+		return this.dirtyBranch;
+	}
+
+	/**
+	 * Return whether the object is unmodified
+	 * since it was last read or saved.
+	 * This does NOT include changes to the object's descendants.
+	 */
+	public final boolean isClean() {
+		return ! this.dirty;
+	}
+
+	/**
+	 * Return whether the object and all of its descendants
+	 * are unmodified since the object and
+	 * its descendants were last read or saved.
+	 */
+	public final boolean isCleanBranch() {
+		return ! this.dirtyBranch;
+	}
+
+	/**
+	 * Set the dirty branch flag setting. This is set to true
+	 * when either the object or one of its descendants becomes dirty.
+	 */
+	private void setIsDirtyBranch(boolean dirtyBranch) {
+		boolean old = this.dirtyBranch;
+		this.dirtyBranch = dirtyBranch;
+		this.firePropertyChanged(DIRTY_BRANCH_PROPERTY, old, dirtyBranch);
+	}
+
+	/**
+	 * Mark the object as dirty and as a dirty branch.
+	 * An object is marked dirty when either a "persistent" attribute
+	 * has changed or its save location has changed.
+	 */
+	private void markDirty() {
+		this.dirty = true;
+		this.markBranchDirty();
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Mark the node and its parent as dirty branches.
+	 * This message is propagated up the containment
+	 * tree when a particular node becomes dirty.
+	 */
+	public void markBranchDirty() {
+		// short-circuit any unnecessary propagation
+		if (this.dirtyBranch) {
+			// if this is already a dirty branch, the parent must be also
+			return;
+		}
+
+		this.setIsDirtyBranch(true);
+		this.markParentBranchDirty();
+	}
+
+	protected void markParentBranchDirty() {
+		if (this.parent != null) {
+			this.parent.markBranchDirty();
+		}
+	}
+
+	/**
+	 * Mark the object and all its descendants as dirty.
+	 * This is used when the save location of some
+	 * top-level object is changed and the entire
+	 * containment tree must be marked dirty so it
+	 * will be written out.
+	 */
+	public final void markEntireBranchDirty() {
+		this.markDirty();
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.markEntireBranchDirty();
+		}
+	}
+
+	/**
+	 * Mark the object and all its descendants as clean.
+	 * Then notify the object's parent that it (the parent)
+	 * might now be a clean branch also.
+	 * Typically used when the object has just been
+	 * read in or written out.
+	 */
+	public final void markEntireBranchClean() {
+		this.cascadeMarkEntireBranchClean();
+		this.markParentBranchCleanIfPossible();
+	}
+
+	protected void markParentBranchCleanIfPossible() {
+		if (this.parent != null) {
+			this.parent.markBranchCleanIfPossible();
+		}
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Mark the node and all its descendants as clean.
+	 * Typically used when the node has just been
+	 * read in or written out.
+	 * This method is for internal use only; it is not for
+	 * client use.
+	 * Not the best of method names.... :-(
+	 */
+	public final void cascadeMarkEntireBranchClean() {
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.cascadeMarkEntireBranchClean();
+		}
+		this.dirty = false;
+		this.setIsDirtyBranch(false);
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * A child node's branch has been marked clean. If the node
+	 * itself is clean and if all of its children are also clean, the
+	 * node's branch can be marked clean. Then, if the node's
+	 * branch is clean, the node will notify its parent that it might
+	 * be clean also. This message is propagated up the containment
+	 * tree when a particular node becomes clean.
+	 */
+	public final void markBranchCleanIfPossible() {
+		// short-circuit any unnecessary propagation
+		if (this.dirty) {
+			// if the object is "locally" dirty, it is still a dirty branch
+			return;
+		}
+
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			if (child.isDirtyBranch()) {
+				return;
+			}
+		}
+
+		this.setIsDirtyBranch(false);
+		this.markParentBranchCleanIfPossible();
+	}
+
+	private boolean aspectIsPersistent(String aspectName) {
+		return ! this.aspectIsTransient(aspectName);
+	}
+
+	private boolean aspectIsTransient(String aspectName) {
+		return this.transientAspectNames().contains(aspectName);
+	}
+
+	/**
+	 * Return a set of the object's transient aspect names.
+	 * These are the aspects that, when they change, will NOT cause the
+	 * object to be marked dirty.
+	 * If you need instance-based calculation of your transient aspects,
+	 * override this method. If class-based calculation is sufficient,
+	 * override #addTransientAspectNamesTo(Set).
+	 */
+	protected final Set<String> transientAspectNames() {
+		synchronized (transientAspectNameSets) {
+			Set<String> transientAspectNames = transientAspectNameSets.get(this.getClass());
+			if (transientAspectNames == null) {
+				transientAspectNames = new HashSet<String>();
+				this.addTransientAspectNamesTo(transientAspectNames);
+				transientAspectNameSets.put(this.getClass(), transientAspectNames);
+			}
+			return transientAspectNames;
+		}
+	}
+
+	/**
+	 * Add the object's transient aspect names to the specified set.
+	 * These are the aspects that, when they change, will NOT cause the
+	 * object to be marked dirty.
+	 * If class-based calculation of your transient aspects is sufficient,
+	 * override this method. If you need instance-based calculation,
+	 * override #transientAspectNames().
+	 */
+	protected void addTransientAspectNamesTo(Set<String> transientAspectNames) {
+		transientAspectNames.add(DIRTY_BRANCH_PROPERTY);
+		transientAspectNames.add(BRANCH_PROBLEMS_LIST);
+		transientAspectNames.add(HAS_BRANCH_PROBLEMS_PROPERTY);
+	// when you override this method, don't forget to include:
+	//	super.addTransientAspectNamesTo(transientAspectNames);
+	}
+
+	/**
+	 * Return the dirty nodes in the object's branch of the tree,
+	 * including the node itself (if appropriate).
+	 * Only really used for testing and debugging.
+	 */
+	public final Iterator<Node> allDirtyNodes() {
+		return new FilteringIterator<Node>(this.allNodes()) {
+			@Override
+			protected boolean accept(Object o) {
+				return (o instanceof AbstractNodeModel) && ((AbstractNodeModel) o).isDirty();
+			}
+		};
+	}
+
+
+	// ********** problems **********
+
+	/**
+	 * Return the node's problems.
+	 * This does NOT include the problems of the node's descendants.
+	 * @see #branchProblems()
+	 */
+	public final Iterator<Problem> problems() {
+		return new CloneIterator<Problem>(this.problems);	// removes are not allowed
+	}
+
+	/**
+	 * Return the size of the node's problems.
+	 * This does NOT include the problems of the node's descendants.
+	 * @see #branchProblemsSize()
+	 */
+	public final int problemsSize() {
+		return this.problems.size();
+	}
+
+	/**
+	 * Return whether the node has problems
+	 * This does NOT include the problems of the node's descendants.
+	 * @see #hasBranchProblems()
+	 */
+	public final boolean hasProblems() {
+		return ! this.problems.isEmpty();
+	}
+
+	/**
+	 * Return all the node's problems along with all the
+	 * node's descendants' problems.
+	 */
+	public final ListIterator<Problem> branchProblems() {
+		return new CloneListIterator<Problem>(this.branchProblems);	// removes are not allowed
+	}
+
+	/**
+	 * Return the size of all the node's problems along with all the
+	 * node's descendants' problems.
+	 */
+	public final int branchProblemsSize() {
+		return this.branchProblems.size();
+	}
+
+	/**
+	 * Return whether the node or any of its descendants have problems.
+	 */
+	public final boolean hasBranchProblems() {
+		return ! this.branchProblems.isEmpty();
+	}
+
+	public final boolean containsBranchProblem(Problem problem) {
+		return this.branchProblems.contains(problem);
+	}
+
+	protected final Problem buildProblem(String messageKey, Object[] messageArguments) {
+		return new DefaultProblem(this, messageKey, messageArguments);
+	}
+
+	protected final Problem buildProblem(String messageKey) {
+		return this.buildProblem(messageKey, EMPTY_PROBLEM_MESSAGE_ARGUMENTS);
+	}
+
+	protected final Problem buildProblem(String messageKey, Object messageArgument) {
+		return this.buildProblem(messageKey, new Object[] {messageArgument});
+	}
+
+	protected final Problem buildProblem(String messageKey, Object messageArgument1, Object messageArgument2) {
+		return this.buildProblem(messageKey, new Object[] {messageArgument1, messageArgument2});
+	}
+
+	protected final Problem buildProblem(String messageKey, Object messageArgument1, Object messageArgument2, Object messageArgument3) {
+		return this.buildProblem(messageKey, new Object[] {messageArgument1, messageArgument2, messageArgument3});
+	}
+
+	/**
+	 * Validate the node and all of its descendants,
+	 * and update their sets of "branch" problems.
+	 * If the node's "branch" problems have changed,
+	 * notify the node's parent.
+	 */
+	public void validateBranch() {
+		if (this.validateBranchInternal()) {
+			// if our "branch" problems have changed, then
+			// our parent must rebuild its "branch" problems also
+			this.rebuildParentBranchProblems();
+		}
+	}
+
+	protected void rebuildParentBranchProblems() {
+		if (this.parent != null) {
+			this.parent.rebuildBranchProblems();
+		}
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Validate the node and all of its descendants,
+	 * and update their sets of "branch" problems.
+	 * Return true if the collection of "branch" problems has changed.
+	 * This method is for internal use only; it is not for
+	 * client use.
+	 */
+	public boolean validateBranchInternal() {
+		// rebuild "branch" problems in children first
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			// ignore the return value because we are going to rebuild our "branch"
+			// problems no matter what, to see if they have changed
+			child.validateBranchInternal();
+		}
+
+		this.problems.clear();
+		this.addProblemsTo(this.problems);
+
+		return this.checkBranchProblems();
+	}
+
+	/**
+	 * Check for any problems and add them to the specified list.
+	 * This method should ONLY add problems for this particular node;
+	 * it should NOT add problems for any of this node's descendants
+	 * or ancestors. (Although there will be times when it is debatable
+	 * as to which node a problem "belongs" to....)
+	 * 
+	 * NB: This method should NOT modify ANY part of the node's state!
+	 * It is a READ-ONLY behavior. ONLY the list of current problems
+	 * passed in to the method should be modified.
+	 */
+	protected void addProblemsTo(List<Problem> currentProblems) {
+		// The default is to do nothing.
+		// When you override this method, don't forget to include:
+	//	super.addProblemsTo(currentProblems);
+	}
+
+	/**
+	 * Rebuild the "branch" problems and return whether they have
+	 * changed.
+	 * NB: The entire collection of "branch" problems must be re-calculated
+	 * with EVERY "significant" change - we cannot keep it in synch via
+	 * change notifications because if a descendant with problems is
+	 * removed or replaced we will not receive notification that its
+	 * problems were removed from our "branch" problems.
+	 */
+	private boolean checkBranchProblems() {
+		List<Problem> oldBranchProblems = new Vector<Problem>(this.branchProblems);
+		int oldSize = this.branchProblems.size();
+
+		this.branchProblems.clear();
+		this.branchProblems.addAll(this.problems);
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			child.addBranchProblemsTo(this.branchProblems);
+		}
+
+		// if the size has changed to or from zero, our virtual flag has changed
+		int newSize = this.branchProblems.size();
+		if ((oldSize == 0) && (newSize != 0)) {
+			this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, false, true);
+		} else if ((oldSize != 0) && (newSize == 0)) {
+			this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, true, false);
+		}
+
+		if (oldBranchProblems.equals(this.branchProblems)) {
+			return false;		// our "branch" problems did not change
+		}
+		// our "branch" problems changed
+		this.fireListChanged(BRANCH_PROBLEMS_LIST);
+		return true;
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Add all the problems of the node and all
+	 * the problems of its descendants to the
+	 * specified collection.
+	 */
+	public final void addBranchProblemsTo(List<Problem> list) {
+		list.addAll(this.branchProblems);
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * A child node's "branch" problems changed;
+	 * therefore the node's "branch" problems have changed also and
+	 * must be rebuilt.
+	 */
+	public final void rebuildBranchProblems() {
+		if ( ! this.checkBranchProblems()) {
+			throw new IllegalStateException("we should not get here unless our \"branch\" problems have changed");
+		}
+		this.rebuildParentBranchProblems();
+	}
+
+	/**
+	 * Clear the node's "branch" problems and the "branch"
+	 * problems of all of its descendants.
+	 * If the node's "branch" problems have changed,
+	 * notify the node's parent.
+	 */
+	public final void clearAllBranchProblems() {
+		if (this.clearAllBranchProblemsInternal()) {
+			// if our "branch" problems have changed, then
+			// our parent must rebuild its "branch" problems also
+			this.rebuildParentBranchProblems();
+		}
+	}
+
+	/**
+	 * INTRA-TREE API
+	 * Clear the node's "branch" problems and the "branch"
+	 * problems of all of its descendants.
+	 * Return true if the collection of "branch" problems has changed.
+	 * This method is for internal use only; it is not for
+	 * client use.
+	 */
+	public final boolean clearAllBranchProblemsInternal() {
+		if (this.branchProblems.isEmpty()) {
+			return false;
+		}
+		for (Iterator<Node> stream = this.children(); stream.hasNext(); ) {
+			Node child = stream.next();		// pull out the child to ease debugging
+			// ignore the return value because we are going to clear our "branch"
+			// problems no matter what
+			child.clearAllBranchProblemsInternal();
+		}
+		this.problems.clear();
+		this.branchProblems.clear();
+		this.firePropertyChanged(HAS_BRANCH_PROBLEMS_PROPERTY, true, false);
+		this.fireListChanged(BRANCH_PROBLEMS_LIST);
+		return true;
+	}
+
+	/**
+	 * Return whether a change to specified aspect requires a re-validation
+	 * of the node's tree.
+	 */
+	private boolean aspectChangeRequiresValidation(String aspectName) {
+		return ! this.aspectChangeDoesNotRequireValidation(aspectName);
+	}
+
+	private boolean aspectChangeDoesNotRequireValidation(String aspectName) {
+		return this.nonValidatedAspectNames().contains(aspectName);
+	}
+
+	/**
+	 * Return a set of the object's "non-validated" aspect names.
+	 * These are the aspects that, when they change, will NOT cause the
+	 * object (or its containing tree) to be validated, i.e. checked for problems.
+	 * If you need instance-based calculation of your "non-validated" aspects,
+	 * override this method. If class-based calculation is sufficient,
+	 * override #addNonValidatedAspectNamesTo(Set).
+	 */
+	protected final Set<String> nonValidatedAspectNames() {
+		synchronized (nonValidatedAspectNameSets) {
+			Set<String> nonValidatedAspectNames = nonValidatedAspectNameSets.get(this.getClass());
+			if (nonValidatedAspectNames == null) {
+				nonValidatedAspectNames = new HashSet<String>();
+				this.addNonValidatedAspectNamesTo(nonValidatedAspectNames);
+				nonValidatedAspectNameSets.put(this.getClass(), nonValidatedAspectNames);
+			}
+			return nonValidatedAspectNames;
+		}
+	}
+
+	/**
+	 * Add the object's "non-validated" aspect names to the specified set.
+	 * These are the aspects that, when they change, will NOT cause the
+	 * object (or its containing tree) to be validated, i.e. checked for problems.
+	 * If class-based calculation of your "non-validated" aspects is sufficient,
+	 * override this method. If you need instance-based calculation,
+	 * override #nonValidatedAspectNames().
+	 */
+	protected void addNonValidatedAspectNamesTo(Set<String> nonValidatedAspectNames) {
+		nonValidatedAspectNames.add(COMMENT_PROPERTY);
+		nonValidatedAspectNames.add(DIRTY_BRANCH_PROPERTY);
+		nonValidatedAspectNames.add(BRANCH_PROBLEMS_LIST);
+		nonValidatedAspectNames.add(HAS_BRANCH_PROBLEMS_PROPERTY);
+	// when you override this method, don't forget to include:
+	//	super.addNonValidatedAspectNamesTo(nonValidatedAspectNames);
+	}
+
+
+	// ********** display methods **********
+
+	/**
+	 * Compare display strings.
+	 */
+	public int compareTo(Node node) {
+		return DEFAULT_COMPARATOR.compare(this, node);
+	}
+
+	/**
+	 * Return a developer-friendly String. If you want something useful for
+	 * displaying in a user interface, use #displayString().
+	 * If you want to give more information in your #toString(),
+	 * override #toString(StringBuffer sb). 
+	 * Whatever you add to that string buffer will show up between the parentheses.
+	 * @see oracle.toplink.workbench.utility.AbstractModel#toString(StringBuffer sb)
+	 * @see #displayString()
+	 */
+	@Override
+	public final String toString() {
+		return super.toString();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AsynchronousValidator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AsynchronousValidator.java
new file mode 100644
index 0000000..58b3e3f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/AsynchronousValidator.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
+
+/**
+ * This implementation of the PluggableValidator.Delegate interface
+ * simply sets a shared "validate" flag to true. This should trigger a
+ * separate "validation" thread to begin validating the appropriate
+ * branch of nodes.
+ */
+public class AsynchronousValidator
+	implements PluggableValidator.Delegate
+{
+	private SynchronizedBoolean validateFlag;
+
+	/**
+	 * Construct a validator delegate with the specified shared
+	 * "validate" flag. This flag should be shared with
+	 * another thread that will perform the actual validation.
+	 */
+	public AsynchronousValidator(SynchronizedBoolean validateFlag) {
+		super();
+		this.validateFlag = validateFlag;
+	}
+
+	/**
+	 * Set the shared "validate" flag to true, triggering
+	 * an asynchronous validation of the appropriate
+	 * branch of nodes.
+	 * @see PluggableValidator.Delegate#validate()
+	 */
+	public void validate() {
+		this.validateFlag.setTrue();
+	}
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.validateFlag);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/DefaultProblem.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/DefaultProblem.java
new file mode 100644
index 0000000..75f5741
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/DefaultProblem.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import java.util.Arrays;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+
+/**
+ * This class is a straightforward implementation of the Problem interface.
+ */
+public class DefaultProblem
+	implements Problem
+{
+	private final Node source;
+	private final String messageKey;
+	private final Object[] messageArguments;
+
+
+	DefaultProblem(Node source, String messageKey, Object[] messageArguments) {
+		super();
+		this.source = source;
+		this.messageKey = messageKey;
+		this.messageArguments = messageArguments;
+	}
+
+
+	// ********** Problem implementation **********
+
+	public Node source() {
+		return this.source;
+	}
+
+	public String messageKey() {
+		return this.messageKey;
+	}
+
+	public Object[] messageArguments() {
+		return this.messageArguments;
+	}
+
+
+	// ********** Object overrides **********
+
+	/**
+	 * We implement #equals(Object) because problems are repeatedly
+	 * re-calculated and the resulting problems merged with the existing
+	 * set of problems; and we want to keep the original problems and
+	 * ignore any freshly-generated duplicates.
+	 * Also, problems are not saved to disk....
+	 */
+	@Override
+	public boolean equals(Object o) {
+		if ( ! (o instanceof Problem)) {
+			return false;
+		}
+		Problem other = (Problem) o;
+		return this.source == other.source()
+				&& this.messageKey.equals(other.messageKey())
+				&& Arrays.equals(this.messageArguments, other.messageArguments());
+	}
+
+	@Override
+	public int hashCode() {
+		return this.source.hashCode() ^ this.messageKey.hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.messageKey);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Node.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Node.java
new file mode 100644
index 0000000..51ed92e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Node.java
@@ -0,0 +1,414 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import java.text.Collator;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.model.ChangeEventDispatcher;
+
+/**
+ * This interface defines the methods that must be implemented
+ * by any class whose instances are to be part of a containment hierarchy
+ * that supports a "dirty" state and validation "problems".
+ * 
+ * Note: Methods marked "INTRA-TREE API" are typically only used by
+ * the nodes themselves, as opposed to clients of the nodes. These
+ * methods are called by a node on either its parent or its children.
+ */
+public interface Node extends Comparable<Node> {
+
+
+	// ********** containment hierarchy (parent/children) **********
+
+	/**
+	 * INTRA-TREE API?
+	 * Return the node's children, which are also nodes.
+	 */
+	Iterator<Node> children();
+
+	/**
+	 * INTRA-TREE API?
+	 * Return the node's parent in the containment hierarchy.
+	 * Most nodes must have a parent.
+	 */
+	Node parent();
+
+	/**
+	 * Return whether the node is a descendant of the specified node.
+	 * By definition, a node is a descendant of itself.
+	 */
+	boolean isDescendantOf(Node node);
+
+	/**
+	 * INTRA-TREE API
+	 * Add the node's "references", and all the node's descendants'
+	 * "references", to the specified collection. "References" are
+	 * objects that are "referenced" by another object, as opposed
+	 * to "owned" by another object.
+	 * This method is of particular concern to Handles, since most
+	 * (hopefully all) "references" are held by Handles.
+	 * @see Reference
+	 * @see #children()
+	 */
+	void addBranchReferencesTo(Collection<Node> branchReferences);
+
+	/**
+	 * INTRA-TREE API?
+	 * Add all the nodes in the object's branch of the tree,
+	 * including the node itself, to the specified collection.
+	 * Only really used for testing and debugging.
+	 */
+	void addAllNodesTo(Collection<Node> nodes);
+
+
+	// ********** model synchronization support **********
+
+	/**
+	 * INTRA-TREE API
+	 * This is a general notification that the specified node has been
+	 * removed from the tree. The node receiving this notification
+	 * should perform any necessary updates to remain in synch
+	 * with the tree (e.g. clearing out or replacing any references
+	 * to the removed node or any of the removed node's descendants).
+	 * @see #isDescendantOf(Node)
+	 */
+	void nodeRemoved(Node node);
+
+	/**
+	 * INTRA-TREE API
+	 * This is a general notification that the specified node has been
+	 * renamed. The node receiving this notification should mark its
+	 * branch dirty if necessary (i.e. it references the renamed node
+	 * or one of its descendants). This method is of particular concern
+	 * to Handles.
+	 * @see #isDescendantOf(Node)
+	 */
+	void nodeRenamed(Node node);
+	
+
+	// ********** dirty flag support **********
+
+	/**
+	 * Return whether any persistent aspects of the node,
+	 * or any of its descendants, have changed since the node and
+	 * its descendants were last read or saved.
+	 */
+	boolean isDirtyBranch();
+		String DIRTY_BRANCH_PROPERTY = "dirtyBranch";
+
+	/**
+	 * INTRA-TREE API
+	 * Mark the node and its parent as dirty branches.
+	 * This message is propagated up the containment
+	 * tree when a particular node becomes dirty.
+	 */
+	void markBranchDirty();
+
+	/**
+	 * Mark the node and all its descendants as dirty.
+	 * This is used when the save location of some
+	 * top-level node is changed and the entire
+	 * containment tree must be marked dirty so it
+	 * will be written out.
+	 */
+	void markEntireBranchDirty();
+
+	/**
+	 * INTRA-TREE API
+	 * A child node's branch has been marked clean. If the node
+	 * itself is clean and if all of its children are also clean, the
+	 * node's branch can be marked clean. Then, if the node's
+	 * branch is clean, the node will notify its parent that it might
+	 * be clean also. This message is propagated up the containment
+	 * tree when a particular node becomes clean.
+	 */
+	void markBranchCleanIfPossible();
+
+	/**
+	 * INTRA-TREE API
+	 * Mark the node and all its descendants as clean.
+	 * Typically used when the node has just been
+	 * read in or written out.
+	 * This method is for internal use only; it is not for
+	 * client use.
+	 * Not the best of method names.... :-(
+	 */
+	void cascadeMarkEntireBranchClean();
+
+
+	// ********** change support **********
+
+	/**
+	 * INTRA-TREE API
+	 * Return a change event dispatcher that will be used to dispatch
+	 * change notifications to listeners.
+	 * Typically only the root node directly holds a dispatcher.
+	 */
+	ChangeEventDispatcher changeEventDispatcher();
+
+	/**
+	 * Set a change event dispatcher that will be used to dispatch
+	 * change notifications to listeners.
+	 * Typically only the root node directly holds a dispatcher.
+	 */
+	void setChangeEventDispatcher(ChangeEventDispatcher changeEventDispatcher);
+
+
+	// ********** problems **********
+
+	/**
+	 * INTRA-TREE API
+	 * Return a validator that will be invoked whenever a
+	 * "validated" aspect of the node tree changes.
+	 * Typically only the root node directly holds a validator.
+	 */
+	Validator validator();
+
+	/**
+	 * Set a validator that will be invoked whenever a
+	 * "validated" aspect of the node tree changes.
+	 * Typically only the root node directly holds a validator.
+	 */
+	void setValidator(Validator validator);
+
+	/**
+	 * Validate the node and its descendants.
+	 * This is an explicit request invoked by a client; and it will
+	 * typically be followed by a call to one of the following methods:
+	 * 	#branchProblems()
+	 * 	#hasBranchProblems()
+	 * Whether the node maintains its problems on the fly
+	 * or waits until this method is called is determined by the
+	 * implementation.
+	 * @see Problem
+	 */
+	void validateBranch();
+
+	/**
+	 * INTRA-TREE API
+	 * Validate the node and all of its descendants,
+	 * and update their sets of "branch" problems.
+	 * Return true if the collection of "branch" problems has changed.
+	 * This method is for internal use only; it is not for
+	 * client use.
+	 */
+	boolean validateBranchInternal();
+
+	/**
+	 * Return all the node's problems along with all the
+	 * node's descendants' problems.
+	 */
+	ListIterator<Problem> branchProblems();
+		String BRANCH_PROBLEMS_LIST = "branchProblems";
+
+	/**
+	 * Return the size of all the node's problems along with all the
+	 * node's descendants' problems.
+	 */
+	int branchProblemsSize();
+
+	/**
+	 * Return whether the node or any of its descendants have problems.
+	 */
+	boolean hasBranchProblems();
+		String HAS_BRANCH_PROBLEMS_PROPERTY = "hasBranchProblems";
+
+	/**
+	 * Return whether the node contains the specified branch problem.
+	 */
+	boolean containsBranchProblem(Problem problem);
+
+	/**
+	 * INTRA-TREE API
+	 * Something changed, rebuild the node's collection of branch problems.
+	 */
+	void rebuildBranchProblems();
+
+	/**
+	 * INTRA-TREE API
+	 * Add the node's problems, and all the node's descendants'
+	 * problems, to the specified list.
+	 * A call to this method should be immediately preceded by a call to
+	 * #validateBranch() or all of the problems might not be
+	 * added to the list.
+	 * @see Problem
+	 */
+	void addBranchProblemsTo(List<Problem> branchProblems);
+
+	/**
+	 * Clear the node's "branch" problems and the "branch"
+	 * problems of all of its descendants.
+	 */
+	void clearAllBranchProblems();
+
+	/**
+	 * INTRA-TREE API
+	 * Clear the node's "branch" problems and the "branch"
+	 * problems of all of its descendants.
+	 * Return true if the collection of "branch" problems has changed.
+	 * This method is for internal use only; it is not for
+	 * client use.
+	 */
+	boolean clearAllBranchProblemsInternal();
+
+
+	// ********** displaying/sorting **********
+
+	/**
+	 * Return a string representation of the model, suitable for sorting.
+	 */
+	String displayString();
+
+
+	// ********** sub-interfaces **********
+
+	/**
+	 * Simple interface defining a "reference" between two nodes.
+	 * @see Node#addBranchReferencesTo(java.util.Collection)
+	 */
+	interface Reference {
+
+		/**
+		 * Return the "source" node of the reference, i.e. the node that
+		 * references the "target" node.
+		 */
+		Node source();
+
+		/**
+		 * Return the "target" node of the reference, i.e. the node that
+		 * is referenced by the "source" node.
+		 */
+		Node target();
+
+	}
+
+
+	/**
+	 * A validator will validate a node as appropriate.
+	 * Typically the validation will
+	 * 	- occur whenever a node has changed
+	 * 	- encompass the entire tree containing the node
+	 * 	- execute asynchronously
+	 */
+	interface Validator {
+
+		/**
+		 * A "significant" aspect has changed;
+		 * validate the node as appropriate
+		 */
+		void validate();
+
+		/**
+		 * Stop all validation of the node until #resume() is called.
+		 * This can be used to improve the performance of any long-running
+		 * action that triggers numerous changes to the node. Be sure to
+		 * match a call to this method with a corresponding call to
+		 * #resume().
+		 */
+		void pause();
+
+		/**
+		 * Resume validation of the node. This method can only be
+		 * called after a matching call to #pause().
+		 */
+		void resume();
+
+	}
+
+
+	// ********** helper implementations **********
+
+	/**
+	 * Straightforward implementation of the Reference interface
+	 * defined above.
+	 */
+	public class SimpleReference implements Reference {
+		private Node source;
+		private Node target;
+		public SimpleReference(Node source, Node target) {
+			super();
+			if (source == null || target == null) {
+				throw new NullPointerException();
+			}
+			this.source = source;
+			this.target = target;
+		}
+		public Node source() {
+			return this.source;
+		}
+		public Node target() {
+			return this.target;
+		}
+		@Override
+		public String toString() {
+			return StringTools.buildToStringFor(this, this.source + " => " + this.target);
+		}
+	}
+
+	/**
+	 * Typical comparator that can be used to sort a collection of nodes.
+	 * Sort based on display string:
+	 * 	- identical objects are equal (which means that cannot
+	 * 		co-exist in a SortedSet)
+	 * 	- use the default collator (which typically interleaves
+	 * 		lower- and upper-case letters)
+	 * 	- allow duplicate display strings (from different objects)
+	 * 	- try to return consistent results for same object pairs
+	 */
+	Comparator<Node> DEFAULT_COMPARATOR =
+		new Comparator<Node>() {
+			public int compare(Node node1, Node node2) {
+				// disallow duplicates based on object identity
+				if (node1 == node2) {
+					return 0;
+				}
+
+				// first compare display strings using the default collator
+				int result = Collator.getInstance().compare(node1.displayString(), node2.displayString());
+				if (result != 0) {
+					return result;
+				}
+
+				// then compare using object-id
+				result = System.identityHashCode(node1) - System.identityHashCode(node2);
+				if (result != 0) {
+					return result;
+				}
+
+				// It's unlikely that we get to this point; but, just in case, we will return -1.
+				// Unfortunately, this introduces some mild unpredictability to the sort order
+				// (unless the objects are always passed into this method in the same order).
+				return -1;		// if all else fails, indicate that o1 < o2
+			}
+			@Override
+			public String toString() {
+				return "Node.DEFAULT_COMPARATOR";
+			}
+		};
+
+
+	/**
+	 * This validator does nothing to validate the node.
+	 */
+	Validator NULL_VALIDATOR =
+		new PluggableValidator(PluggableValidator.Delegate.NULL_DELEGATE) {
+			@Override
+			public String toString() {
+				return "Node.NULL_VALIDATOR";
+			}
+		};
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/NodeModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/NodeModel.java
new file mode 100644
index 0000000..c5eebb0
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/NodeModel.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import org.eclipse.jpt.utility.internal.model.Model;
+
+/**
+ * Some nodes are models....
+ */
+public interface NodeModel extends Node, Model {
+	// no additional behavior
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/PluggableValidator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/PluggableValidator.java
new file mode 100644
index 0000000..9a21a6e
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/PluggableValidator.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
+
+/**
+ * This implementation of the Validator interface implements the
+ * pause/resume portion of the protocol, but delegates the actual
+ * validation to a "pluggable" delegate.
+ */
+public class PluggableValidator implements Node.Validator {
+	private boolean pause;
+	private Delegate delegate;
+
+
+	/**
+	 * Convenience factory method.
+	 */
+	public static Node.Validator buildAsynchronousValidator(SynchronizedBoolean validateFlag) {
+		return new PluggableValidator(new AsynchronousValidator(validateFlag));
+	}
+
+	/**
+	 * Convenience factory method.
+	 */
+	public static Node.Validator buildSynchronousValidator(Node node) {
+		return new PluggableValidator(new SynchronousValidator(node));
+	}
+
+	/**
+	 * Construct a validator with the specified delegate.
+	 */
+	public PluggableValidator(Delegate delegate) {
+		super();
+		this.pause = false;
+		this.delegate = delegate;
+	}
+
+	public void validate() {
+		if ( ! this.pause) {
+			this.delegate.validate();
+		}
+	}
+
+	public void pause() {
+		if (this.pause) {
+			throw new IllegalStateException("already paused");
+		}
+		this.pause = true;
+	}
+
+	public void resume() {
+		if ( ! this.pause) {
+			throw new IllegalStateException("not paused");
+		}
+		this.pause = false;
+		// validate all the changes that occurred while the validation was paused
+		this.delegate.validate();
+	}
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.delegate);
+	}
+
+
+	// ********** member interface **********
+
+	/**
+	 * Interface implemented by any delegates of a pluggable validator.
+	 */
+	public interface Delegate {
+
+		/**
+		 * The validator is not "paused" - perform the appropriate validation.
+		 */
+		void validate();
+
+
+		/**
+		 * This delegate does nothing.
+		 */
+		Delegate NULL_DELEGATE =
+			new PluggableValidator.Delegate() {
+				public void validate() {
+					// do nothing
+				}
+				@Override
+				public String toString() {
+					return "NULL_DELEGATE";
+				}
+			};
+
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Problem.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Problem.java
new file mode 100644
index 0000000..4f8e730
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/Problem.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+/**
+ * Define an interface describing the problems associated with a node.
+ */
+public interface Problem {
+
+	/**
+	 * Return the node most closely associated with the problem.
+	 */
+	Node source();
+
+	/**
+	 * Return a key that can be used to uniquely identify the problem's message.
+	 */
+	String messageKey();
+
+	/**
+	 * Return the arguments associate with the problem's message.
+	 */
+	Object[] messageArguments();
+
+	/**
+	 * Return whether the problem is equal to the specified object.
+	 * It is equal if the specified object is a implementation of the
+	 * Problem interface and its source, message key, and message
+	 * arguments are all equal to this problem's.
+	 */
+	boolean equals(Object o);
+
+	/**
+	 * Return the problem's hash code, which should calculated as an
+	 * XOR of the source's hash code and the message key's hash code.
+	 */
+	int hashCode();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/RunnableValidation.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/RunnableValidation.java
new file mode 100644
index 0000000..3be7c0d
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/RunnableValidation.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
+
+/**
+ * This implementation of Runnable will asynchronously validate
+ * a branch of nodes. It will wait until a shared "validate" flag is
+ * set to validate the branch. Once the the branch is validated,
+ * the thread will quiesce until the flag is set again.
+ * 
+ * There are two ways to stop this thread:
+ * 	- Thread.interrupt()
+ * 	- set the "continue" flag to false
+ * For now, these two are equivalent; but in the future we might
+ * pass the "continue" flag to the Node.validate(Node.ProblemSynchronizer)
+ * method so we can short-circuit the validation instead of waiting
+ * until the entire branch is validated.
+ */
+public class RunnableValidation
+	implements Runnable
+{
+	/** The node whose branch this thread will validate. */
+	private Node node;
+
+	/** When this flag is set to true, we kick off the validation routine. */
+	private SynchronizedBoolean validateFlag;
+
+	/** When this flag is set to false, we allow this thread to die. */
+	private SynchronizedBoolean continueFlag;
+
+	/** Log any exceptions encountered during validation with the following settings. */
+	private Logger exceptionLogger;
+	private Level exceptionLevel;
+	private String exceptionMessage;
+
+
+	/**
+	 * Construct a validation thread.
+	 */
+	public RunnableValidation(
+			Node node,
+			SynchronizedBoolean validateFlag,
+			SynchronizedBoolean continueFlag,
+			Logger exceptionLogger,
+			Level exceptionLevel,
+			String exceptionMessage
+	) {
+		super();
+		this.node = node;
+		this.validateFlag = validateFlag;
+		this.continueFlag = continueFlag;
+		this.exceptionLogger = exceptionLogger;
+		this.exceptionLevel = exceptionLevel;
+		this.exceptionMessage = exceptionMessage;
+	}
+
+
+	// ********** Runnable Implementation **********
+
+	/**
+	 * Loop while the "continue" flag is true and the thread
+	 * has not been interrupted by another thread.
+	 * In each loop: Wait until the "validate" flag is set to true,
+	 * then set it back to false and validate the branch of nodes.
+	 */
+	public void run() {
+		while (this.continueFlag.isTrue()) {
+			try {
+				this.validateFlag.waitToSetFalse();
+			} catch (InterruptedException ex) {
+				// we were interrupted while waiting, must be quittin' time
+				return;
+			}
+			this.validateNode();
+		}
+	}
+
+	/**
+	 * Validate the node, logging any exceptions.
+	 * If an exception occurs, we terminate the validation until the
+	 * "validation" flag is set again. Some exceptions occur because
+	 * of concurrent changes to the model that occur *after* validation
+	 * starts but before it completes an entire pass over the model. If that
+	 * is the case, things should be OK; because the exception will be
+	 * caught and the "validation" flag will have been set again *during* the
+	 * initial validation pass. So when we return from catching the exception
+	 * we will simply re-start the validation, hopefully with the model in
+	 * a consistent state that will prevent another exception from
+	 * occurring. Of course, if we have any exceptions that are *not*
+	 * the result of the model being in an inconsistent state, we will
+	 * probably fill the log; and those exceptions are bugs that need
+	 * to be fixed. (!) Hopefully the user will notice the enormous log and
+	 * contact support....  ~bjv
+	 */
+	private void validateNode() {
+		try {
+			this.node.validateBranch();
+		} catch (Throwable ex) {
+			this.logException(ex);
+		}
+	}
+
+	/**
+	 * We need to do all this because Logger#log(LogRecord) does not pass through
+	 * Logger#doLog(LogRecord) like all the other Logger#log(...) methods.
+	 */
+	private void logException(Throwable ex) {
+		LogRecord logRecord = new LogRecord(this.exceptionLevel, this.exceptionMessage);
+		logRecord.setParameters(new Object[] { this.node.displayString() });
+		logRecord.setThrown(ex);
+		logRecord.setLoggerName(this.exceptionLogger.getName());
+		logRecord.setResourceBundle(this.exceptionLogger.getResourceBundle());
+		this.exceptionLogger.log(logRecord);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/SynchronousValidator.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/SynchronousValidator.java
new file mode 100644
index 0000000..7ff3204
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/node/SynchronousValidator.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.node;
+
+import org.eclipse.jpt.utility.internal.StringTools;
+
+/**
+ * This implementation of the PluggableValidator.Delegate interface
+ * will validate the node immediately.
+ * 
+ * This is useful for debugging in a single thread or generating
+ * problem reports.
+ */
+public class SynchronousValidator
+	implements PluggableValidator.Delegate
+{
+	private Node node;
+
+	/**
+	 * Construct a validator that will immediately validate the
+	 * specified node.
+	 */
+	public SynchronousValidator(Node node) {
+		super();
+		this.node = node;
+	}
+
+	public void validate() {
+		this.node.validateBranch();
+	}
+
+	@Override
+	public String toString() {
+		return StringTools.buildToStringFor(this, this.node);
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/.classpath b/jpa/tests/org.eclipse.jpt.core.tests/.classpath
deleted file mode 100644
index db34e47..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/.classpath
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
-		<accessrules>
-			<accessrule kind="accessible" pattern="org/eclipse/wst/**"/>
-			<accessrule kind="accessible" pattern="org/eclipse/jst/**"/>
-			<accessrule kind="accessible" pattern="org/eclipse/jpt/**"/>
-		</accessrules>
-	</classpathentry>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/.cvsignore b/jpa/tests/org.eclipse.jpt.core.tests/.cvsignore
deleted file mode 100644
index ba077a4..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/.project b/jpa/tests/org.eclipse.jpt.core.tests/.project
deleted file mode 100644
index 08395a8..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.core.tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/.settings/org.eclipse.core.resources.prefs b/jpa/tests/org.eclipse.jpt.core.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 88638b5..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 27 15:10:20 EDT 2007
-eclipse.preferences.version=1
-encoding/<project>=ISO-8859-1
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/.settings/org.eclipse.jdt.core.prefs b/jpa/tests/org.eclipse.jpt.core.tests/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index a2f6604..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,7 +0,0 @@
-#Sun May 27 14:58:31 EDT 2007
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/META-INF/MANIFEST.MF b/jpa/tests/org.eclipse.jpt.core.tests/META-INF/MANIFEST.MF
deleted file mode 100644
index be27b10..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,25 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-Vendor: %providerName
-Bundle-SymbolicName: org.eclipse.jpt.core.tests
-Bundle-Version: 1.0.0
-Bundle-Localization: plugin
-Require-Bundle: org.eclipse.core.resources,
- org.eclipse.core.runtime,
- org.eclipse.emf.ecore,
- org.eclipse.emf.ecore.xmi,
- org.eclipse.jdt.core,
- org.eclipse.jem,
- org.eclipse.jpt.core,
- org.eclipse.jpt.utility,
- org.eclipse.wst.common.emf,
- org.eclipse.wst.common.project.facet.core,
- org.junit
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.jpt.core.tests.internal;x-internal:=true,
- org.eclipse.jpt.core.tests.internal.content.java.mappings;x-internal:=true,
- org.eclipse.jpt.core.tests.internal.jdtutility;x-internal:=true,
- org.eclipse.jpt.core.tests.internal.model;x-internal:=true,
- org.eclipse.jpt.core.tests.internal.platform;x-internal:=true,
- org.eclipse.jpt.core.tests.internal.projects;x-internal:=true
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/about.html b/jpa/tests/org.eclipse.jpt.core.tests/about.html
deleted file mode 100644
index 9e73bda..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/about.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<HTML>
-
-<head>
-<title>About</title>
-<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
-</head>
-
-<BODY lang="EN-US">
-
-<H3>About This Content</H3>
-
-<P>June 06, 2007</P>
-
-<H3>License</H3>
-
-<P>The Eclipse Foundation makes available all content in this plug-in 
-("Content"). Unless otherwise indicated below, the Content is provided to you 
-under the terms and conditions of the Eclipse Public License Version 1.0 
-("EPL"). A copy of the EPL is available at
-<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
-For purposes of the EPL, "Program" will mean the Content.</P>
-
-<P>If you did not receive this Content directly from the Eclipse Foundation, the 
-Content is being redistributed by another party ("Redistributor") and different 
-terms and conditions may apply to your use of any object code in the Content. 
-Check the Redistributor's license that was provided with the Content. If no such 
-license exists, contact the Redistributor. Unless otherwise indicated below, the 
-terms and conditions of the EPL still apply to any source code in the Content 
-and such source code may be obtained at
-<A href="http://www.eclipse.org/">http://www.eclipse.org/</A>.</P>
-
-</BODY>
-</HTML>
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/build.properties b/jpa/tests/org.eclipse.jpt.core.tests/build.properties
deleted file mode 100644
index 9bf11f7..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/build.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-###############################################################################
-# Copyright (c) 2006, 2007 Oracle.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     Oracle. - initial API and implementation
-###############################################################################
-javacSource = 1.5
-javacTarget = 1.5
-bin.includes = .,\
-               META-INF/,\
-               about.html,\
-               test.xml,\
-               plugin.properties
-source.. = src/
-output.. = bin/
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/plugin.properties b/jpa/tests/org.eclipse.jpt.core.tests/plugin.properties
deleted file mode 100644
index 6ebf8db..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/plugin.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-###############################################################################
-#  Copyright (c) 2006, 2007 Oracle. All rights reserved. This
-#  program and the accompanying materials are made available under the terms of
-#  the Eclipse Public License v1.0 which accompanies this distribution, and is
-#  available at http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: Oracle. - initial API and implementation
-###############################################################################
-# ====================================================================
-# To code developer:
-#   Do NOT change the properties between this line and the
-#   "%%% END OF TRANSLATED PROPERTIES %%%" line.
-#   Make a new property name, append to the end of the file and change
-#   the code to use the new property.
-# ====================================================================
-
-# ====================================================================
-# %%% END OF TRANSLATED PROPERTIES %%%
-# ====================================================================
-
-pluginName=Java Persistence API Core Tests
-providerName=Eclipse.org
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/JptCoreTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/JptCoreTests.java
deleted file mode 100644
index baf5150..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/JptCoreTests.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.eclipse.jpt.core.tests.internal.content.java.mappings.JptCoreContentJavaMappingsTests;
-import org.eclipse.jpt.core.tests.internal.jdtutility.JptCoreJdtUtilityTests;
-import org.eclipse.jpt.core.tests.internal.model.JptCoreModelTests;
-import org.eclipse.jpt.core.tests.internal.platform.JptCorePlatformTests;
-
-/**
- * Runs all JPT Core Tests
- */
-public class JptCoreTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(JptCoreTests.class.getName());
-		suite.addTest(JptCoreContentJavaMappingsTests.suite());
-		suite.addTest(JptCoreModelTests.suite());
-		suite.addTest(JptCoreJdtUtilityTests.suite());
-		suite.addTest(JptCorePlatformTests.suite());
-		return suite;
-	}
-	
-	private JptCoreTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/ProjectUtility.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/ProjectUtility.java
deleted file mode 100644
index ac9e78a..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/ProjectUtility.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2007 Oracle. 
- *  All rights reserved.  This program and the accompanying materials 
- *  are made available under the terms of the Eclipse Public License v1.0 
- *  which accompanies this distribution, and is available at 
- *  http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: 
- *  	Oracle - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.tests.internal;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.AssertionFailedException;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-/**
- * Copied from org.eclipse.wst.common.tests
- */
-public class ProjectUtility {
-    public static IProject[] getAllProjects() {
-    	IProject[] projects = new IProject[0];
-    	try {
-        projects =  ResourcesPlugin.getWorkspace().getRoot().getProjects();
-    	} catch (AssertionFailedException ex) {
-    		// Catch Malformed tree exception that occurs from time to time...
-    	}
-    	return projects;
-    }
-    public static void deleteAllProjects() throws Exception {
-        //closing projects and tread work in here is a hack because of a BeanInfo bug holding
-        //onto jars loaded in another VM
-        
-//        for (int i = 0; i < projects.length; i++) {
-//            if (projects[i].exists()) {
-//                projects[i].close(null); // This should signal the extra VM to kill itself
-//            }
-//        }
- //       Thread.yield(); // give the VM a chance to die
-        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor monitor) {
-				IProject[] projects = getAllProjects();
-				for (int i = 0; i < projects.length; i++) {
-					IProject project = projects[i];
-					boolean success = false;
-					Exception lastException = null;
-					// Don't make 2^12 is about 4 seconds which is the max we
-					// will wait for the VM to die
-					for (int j = 0; j < 13 && !success; j++) {
-						try {
-							if (project.exists()) {
-								project.delete(true, true, null);
-								ResourcesPlugin.getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, null);
-							}
-							success = true;
-						} catch (Exception e) {
-							lastException = e;
-							if (project.exists()) {
-								try {
-									project.close(null);
-									project.open(null);
-								} catch (Exception e2) {
-									// do nothing
-								}
-							}
-							try {
-								Thread.sleep((int) Math.pow(2, j));
-							} catch (InterruptedException e1) {
-								// do nothing
-							} // if the VM isn't dead, try sleeping
-						}
-					}
-					if (!success && lastException != null) {
-						//Logger.getLogger().log("Problem while deleting: " + lastException.getMessage());
-//						 Assert.fail("Caught Exception=" +
-//						 lastException.getMessage() + " when deleting project=" + project.getName());
-					}
-				}
-			}
-		};
-		try {
-			ResourcesPlugin.getWorkspace().run(runnable, null);
-		} catch (CoreException ce) {
-			// do nothing
-		}
-        //verifyNoProjects();
-    }
-}
\ No newline at end of file
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JavaEntityTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JavaEntityTests.java
deleted file mode 100644
index bbf7a95..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JavaEntityTests.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2007 Oracle. 
- *  All rights reserved.  This program and the accompanying materials 
- *  are made available under the terms of the Eclipse Public License v1.0 
- *  which accompanies this distribution, and is available at 
- *  http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: 
- *  	Oracle - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.content.java.mappings;
-
-import java.util.Iterator;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jpt.core.internal.content.java.IJavaTypeMapping;
-import org.eclipse.jpt.core.internal.content.java.mappings.JPA;
-import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
-
-public class JavaEntityTests extends JpaJavaTestCase {
-
-	public JavaEntityTests(String name) {
-		super(name);
-	}
-
-	private void createTestEntity1() throws CoreException {
-		this.createTestType(new DefaultAnnotationWriter() {
-			@Override
-			public Iterator<String> imports() {
-				return new ArrayIterator<String>(JPA.ENTITY);
-			}
-			@Override
-			public void appendTypeAnnotationTo(StringBuffer sb) {
-				sb.append("@Entity");
-			}
-		});
-		this.synchPersistenceXml();
-	}
-
-	public void testGetName() throws Exception {
-		this.createTestEntity1();
-		IJavaTypeMapping typeMapping = this.javaPersistentTypeNamed(FULLY_QUALIFIED_TYPE_NAME).getMapping();
-		assertEquals(TYPE_NAME, typeMapping.getName());
-	}
-
-// TODO we can only execute 1 test for now...
-//	public void testGetKey() throws Exception {
-//		this.createTestEntity1();
-//		IJavaTypeMapping typeMapping = this.javaPersistentTypeNamed(FULLY_QUALIFIED_TYPE_NAME).getMapping();
-//		assertEquals(IMappingKeys.ENTITY_TYPE_MAPPING_KEY, typeMapping.getKey());
-//	}
-//
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JpaJavaTestCase.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JpaJavaTestCase.java
deleted file mode 100644
index ba028e9..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JpaJavaTestCase.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2007 Oracle. 
- *  All rights reserved.  This program and the accompanying materials 
- *  are made available under the terms of the Eclipse Public License v1.0 
- *  which accompanies this distribution, and is available at 
- *  http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: 
- *  	Oracle - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.content.java.mappings;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jpt.core.internal.IJpaFile;
-import org.eclipse.jpt.core.internal.content.java.JavaPersistentType;
-import org.eclipse.jpt.core.internal.content.java.JpaCompilationUnit;
-import org.eclipse.jpt.core.internal.jdtutility.Type;
-import org.eclipse.jpt.core.internal.synch.SynchronizeClassesJob;
-import org.eclipse.jpt.core.tests.internal.jdtutility.AnnotationTestCase;
-import org.eclipse.jpt.core.tests.internal.projects.TestJavaProject;
-import org.eclipse.jpt.core.tests.internal.projects.TestJpaProject;
-import org.eclipse.jpt.utility.internal.ClassTools;
-
-public abstract class JpaJavaTestCase extends AnnotationTestCase {
-
-	public JpaJavaTestCase(String name) {
-		super(name);
-	}
-
-	@Override
-	protected TestJavaProject buildJavaProject(String projectName, boolean autoBuild) throws Exception {
-		return new TestJpaProject(projectName, autoBuild);
-	}
-
-	protected TestJpaProject jpaProject() {
-		return (TestJpaProject) this.javaProject;
-	}
-
-	protected JavaPersistentType javaPersistentTypeNamed(String typeName) {
-		for (IJpaFile jpaFile : this.jpaProject().getJpaProject().jpaFiles(JavaCore.JAVA_SOURCE_CONTENT_TYPE)) {
-			JpaCompilationUnit cu = (JpaCompilationUnit) jpaFile.getContent();
-			for (JavaPersistentType pt : cu.getTypes()) {
-				if (pt.fullyQualifiedTypeName().equals(typeName)) {
-					return pt;
-				}
-			}
-		}
-		throw new IllegalArgumentException("missing type: " + typeName);
-	}
-
-	protected Type typeNamed(String typeName) {
-		return this.javaPersistentTypeNamed(typeName).getType();
-	}
-
-	protected void synchPersistenceXml() {
-		SynchronizeClassesJob job = new SynchronizeClassesJob(this.jpaProject().getProject().getFile("src/META-INF/persistence.xml"));
-		ClassTools.executeMethod(job, "run", IProgressMonitor.class, new NullProgressMonitor());
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/AnnotationTestCase.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/AnnotationTestCase.java
deleted file mode 100644
index 87d6169..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/AnnotationTestCase.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import java.util.Iterator;
-import java.util.List;
-import junit.framework.TestCase;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.MemberValuePair;
-import org.eclipse.jdt.core.dom.NormalAnnotation;
-import org.eclipse.jdt.core.dom.NumberLiteral;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jpt.core.internal.jdtutility.FieldAttribute;
-import org.eclipse.jpt.core.internal.jdtutility.MethodAttribute;
-import org.eclipse.jpt.core.internal.jdtutility.Type;
-import org.eclipse.jpt.core.tests.internal.projects.TestJavaProject;
-import org.eclipse.jpt.core.tests.internal.projects.TestJavaProject.SourceWriter;
-import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
-import org.eclipse.jpt.utility.internal.iterators.SingleElementIterator;
-
-/**
- * Provide an easy(?) way to build an annotated source file.
- * The type must be created by calling one of the #createType() methods
- * before calling any of the various helper methods (i.e. the type is *not*
- * created during #setUp()).
- */
-public abstract class AnnotationTestCase extends TestCase {
-	protected TestJavaProject javaProject;
-
-	protected static final String CR = System.getProperty("line.separator");
-	protected static final String PROJECT_NAME = "AnnotationTestProject";
-	protected static final String PACKAGE_NAME = "test";
-	protected static final String TYPE_NAME = "AnnotationTestType";
-	protected static final String FULLY_QUALIFIED_TYPE_NAME = PACKAGE_NAME + "." + TYPE_NAME;
-	protected static final String FILE_NAME = TYPE_NAME + ".java";
-
-	protected static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-
-	// ********** TestCase behavior **********
-
-	protected AnnotationTestCase(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.javaProject = this.buildJavaProject(PROJECT_NAME, false);  // false = no auto-build
-	}
-
-	protected TestJavaProject buildJavaProject(String projectName, boolean autoBuild) throws Exception {
-		return new TestJavaProject(projectName, autoBuild);  // false = no auto-build
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-//		this.dumpSource();
-		this.javaProject.dispose();
-		this.javaProject = null;
-		super.tearDown();
-	}
-
-	protected void dumpSource() throws Exception {
-		System.out.println("*** " + this.getName() + " ****");
-		System.out.println(this.source());
-		System.out.println();
-	}
-
-
-	// ********** type creation **********
-
-	/**
-	 * create an un-annotated type
-	 */
-	protected IType createTestType() throws CoreException {
-		return this.createTestType(new DefaultAnnotationWriter());
-	}
-
-	/**
-	 * shortcut for simply adding an annotation to the 'id' field
-	 */
-	protected IType createTestType(final String annotationImport, final String idFieldAnnotation) throws CoreException {
-		return this.createTestType(new DefaultAnnotationWriter() {
-			@Override
-			public Iterator<String> imports() {
-				return (annotationImport == null) ?
-					EmptyIterator.<String>instance()
-				:
-					new SingleElementIterator<String>(annotationImport);
-			}
-			@Override
-			public void appendIdFieldAnnotationTo(StringBuffer sb) {
-				sb.append(idFieldAnnotation);
-			}
-		});
-	}
-
-	/**
-	 * shortcut for simply adding a fully-qualified annotation to the 'id' field
-	 */
-	protected IType createTestType(final String idFieldAnnotation) throws CoreException {
-		return this.createTestType(null, idFieldAnnotation);
-	}
-
-	protected IType createTestType(AnnotationWriter annotationWriter) throws CoreException {
-		return this.javaProject.createType(PACKAGE_NAME, FILE_NAME, this.createSourceWriter(annotationWriter));
-	}
-
-	protected SourceWriter createSourceWriter(AnnotationWriter annotationWriter) {
-		return new AnnotatedSourceWriter(annotationWriter);
-	}
-
-	protected void appendSourceTo(StringBuffer sb, AnnotationWriter annotationWriter) {
-		sb.append(CR);
-		for (Iterator<String> stream = annotationWriter.imports(); stream.hasNext(); ) {
-			sb.append("import ");
-			sb.append(stream.next());
-			sb.append(";");
-			sb.append(CR);
-		}
-		annotationWriter.appendTypeAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("public class ").append(TYPE_NAME).append(" {").append(CR);
-		sb.append(CR);
-		sb.append("    ");
-		annotationWriter.appendIdFieldAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("    private int id;").append(CR);
-		sb.append(CR);
-		sb.append("    ");
-		annotationWriter.appendNameFieldAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("    private String name;").append(CR);
-		sb.append(CR);
-		sb.append("    ");
-		annotationWriter.appendGetIdMethodAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("    public int getId() {").append(CR);
-		sb.append("        return this.id;").append(CR);
-		sb.append("    }").append(CR);
-		sb.append(CR);
-		sb.append("    ");
-		annotationWriter.appendSetIdMethodAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("    public void setId(int id) {").append(CR);
-		sb.append("        this.id = id;").append(CR);
-		sb.append("    }").append(CR);
-		sb.append(CR);
-		sb.append("    ");
-		annotationWriter.appendGetNameMethodAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("    public String getName() {").append(CR);
-		sb.append("        return this.name;").append(CR);
-		sb.append("    }").append(CR);
-		sb.append(CR);
-		sb.append("    ");
-		annotationWriter.appendSetNameMethodAnnotationTo(sb);
-		sb.append(CR);
-		sb.append("    public void setTestField(String testField) {").append(CR);
-		sb.append("        this.testField = testField;").append(CR);
-		sb.append("    }").append(CR);
-		sb.append(CR);
-		sb.append("}").append(CR);
-	}
-
-
-	// ********** queries **********
-
-	protected IType jdtType() throws JavaModelException {
-		return this.javaProject.findType(FULLY_QUALIFIED_TYPE_NAME);
-	}
-
-	protected Type testType() throws JavaModelException {
-		return new Type(this.jdtType());
-	}
-
-	protected FieldAttribute idField() throws JavaModelException {
-		return this.fieldNamed("id");
-	}
-
-	protected FieldAttribute nameField() throws JavaModelException {
-		return this.fieldNamed("name");
-	}
-
-	protected FieldAttribute fieldNamed(String fieldName) throws JavaModelException {
-		return new FieldAttribute(this.jdtType().getField(fieldName));
-	}
-
-	protected MethodAttribute idGetMethod() throws JavaModelException {
-		return this.methodNamed("getId");
-	}
-
-	protected MethodAttribute nameGetMethod() throws JavaModelException {
-		return this.methodNamed("getName");
-	}
-
-	protected MethodAttribute methodNamed(String methodName) throws JavaModelException {
-		return this.method(methodName, EMPTY_STRING_ARRAY);
-	}
-
-	protected MethodAttribute method(String methodName, String[] parameterTypeSignatures) throws JavaModelException {
-		return new MethodAttribute(this.jdtType().getMethod(methodName, parameterTypeSignatures));
-	}
-
-	protected String source() throws JavaModelException {
-		return this.jdtType().getOpenable().getBuffer().getContents();
-	}
-
-
-	// ********** test validation **********
-
-	protected void assertSourceContains(String s) throws JavaModelException {
-		String source = this.source();
-		boolean found = source.indexOf(s) > -1;
-		if ( ! found) {
-			String msg = "source does not contain the expected string: " + s + " (see System console)";
-			System.out.println("*** " + this.getName() + " ****");
-			System.out.println(msg);
-			System.out.println(source);
-			System.out.println();
-			fail(msg);
-		}
-	}
-
-	protected void assertSourceDoesNotContain(String s) throws JavaModelException {
-		String source = this.source();
-		int pos = source.indexOf(s);
-		if (pos != -1) {
-			String msg = "unexpected string in source (position: " + pos + "): " + s + " (see System console)";
-			System.out.println("*** " + this.getName() + " ****");
-			System.out.println(msg);
-			System.out.println(source);
-			System.out.println();
-			fail(msg);
-		}
-	}
-
-
-	// ********** manipulate annotations **********
-
-	/**
-	 * Return the *first* member value pair for the specified annotation element
-	 * with the specified name.
-	 * Return null if the annotation has no such element.
-	 */
-	protected MemberValuePair memberValuePair(NormalAnnotation annotation, String elementName) {
-		for (MemberValuePair pair : this.values(annotation)) {
-			if (pair.getName().getFullyQualifiedName().equals(elementName)) {
-				return pair;
-			}
-		}
-		return null;
-	}
-
-	@SuppressWarnings("unchecked")
-	protected List<MemberValuePair> values(NormalAnnotation na) {
-		return na.values();
-	}
-
-	/**
-	 * check for null member value pair
-	 */
-	protected Expression valueInternal(MemberValuePair pair) {
-		return (pair == null) ? null : pair.getValue();
-	}
-
-	/**
-	 * Return the value of the *first* annotation element
-	 * with the specified name.
-	 * Return null if the annotation has no such element.
-	 */
-	protected Expression annotationElementValue(NormalAnnotation annotation, String elementName) {
-		return this.valueInternal(this.memberValuePair(annotation, elementName));
-	}
-
-	/**
-	 * Return the value of the *first* annotation element
-	 * with the specified name.
-	 * Return null if the annotation has no such element.
-	 */
-	protected Expression annotationElementValue(SingleMemberAnnotation annotation, String elementName) {
-		return elementName.equals("value") ? annotation.getValue() : null;
-	}
-
-	/**
-	 * Return the value of the *first* annotation element
-	 * with the specified name.
-	 * Return null if the annotation has no such element.
-	 * (An element name of "value" will return the value of a single
-	 * member annotation.)
-	 */
-	protected Expression annotationElementValue(Annotation annotation, String elementName) {
-		if (annotation.isNormalAnnotation()) {
-			return this.annotationElementValue((NormalAnnotation) annotation, elementName);
-		}
-		if (annotation.isSingleMemberAnnotation()) {
-			return this.annotationElementValue((SingleMemberAnnotation) annotation, elementName);
-		}
-		return null;
-	}
-
-	/**
-	 * Build a number literal and set its initial value to the specified literal.
-	 */
-	protected NumberLiteral newNumberLiteral(AST ast, int value) {
-		return ast.newNumberLiteral(Integer.toString(value));
-	}
-
-	/**
-	 * Build a string literal and set its initial value.
-	 */
-	protected StringLiteral newStringLiteral(AST ast, String value) {
-		StringLiteral stringLiteral = ast.newStringLiteral();
-		stringLiteral.setLiteralValue(value);
-		return stringLiteral;
-	}
-
-	protected MemberValuePair newMemberValuePair(AST ast, SimpleName name, Expression value) {
-		MemberValuePair pair = ast.newMemberValuePair();
-		pair.setName(name);
-		pair.setValue(value);
-		return pair;
-	}
-
-	protected MemberValuePair newMemberValuePair(AST ast, String name, Expression value) {
-		return this.newMemberValuePair(ast, ast.newSimpleName(name), value);
-	}
-
-	protected MemberValuePair newMemberValuePair(AST ast, String name, String value) {
-		return this.newMemberValuePair(ast, name, this.newStringLiteral(ast, value));
-	}
-
-	protected MemberValuePair newMemberValuePair(AST ast, String name, int value) {
-		return this.newMemberValuePair(ast, name, this.newNumberLiteral(ast, value));
-	}
-
-	/**
-	 * Add the specified member value pair to the specified annotation.
-	 * Return the resulting annotation.
-	 */
-	protected NormalAnnotation addMemberValuePair(NormalAnnotation annotation, MemberValuePair pair) {
-		this.values(annotation).add(pair);
-		return annotation;
-	}
-
-	/**
-	 * Add the specified member value pair to the specified annotation.
-	 * Return the resulting annotation.
-	 */
-	protected NormalAnnotation addMemberValuePair(NormalAnnotation annotation, String name, int value) {
-		return this.addMemberValuePair(annotation, this.newMemberValuePair(annotation.getAST(), name, value));
-	}
-
-	/**
-	 * Add the specified member value pair to the specified annotation.
-	 * Return the resulting annotation.
-	 */
-	protected NormalAnnotation addMemberValuePair(NormalAnnotation annotation, String name, String value) {
-		return this.addMemberValuePair(annotation, this.newMemberValuePair(annotation.getAST(), name, value));
-	}
-
-
-	// ********** member classes **********
-
-	public interface AnnotationWriter {
-		Iterator<String> imports();
-		void appendTypeAnnotationTo(StringBuffer sb);
-		void appendIdFieldAnnotationTo(StringBuffer sb);
-		void appendNameFieldAnnotationTo(StringBuffer sb);
-		void appendGetIdMethodAnnotationTo(StringBuffer sb);
-		void appendSetIdMethodAnnotationTo(StringBuffer sb);
-		void appendGetNameMethodAnnotationTo(StringBuffer sb);
-		void appendSetNameMethodAnnotationTo(StringBuffer sb);
-	}
-
-	public static class DefaultAnnotationWriter implements AnnotationWriter {
-		public Iterator<String> imports() {return EmptyIterator.instance();}
-		public void appendTypeAnnotationTo(StringBuffer sb) {/* do nothing */}
-		public void appendIdFieldAnnotationTo(StringBuffer sb) {/* do nothing */}
-		public void appendNameFieldAnnotationTo(StringBuffer sb) {/* do nothing */}
-		public void appendGetIdMethodAnnotationTo(StringBuffer sb) {/* do nothing */}
-		public void appendSetIdMethodAnnotationTo(StringBuffer sb) {/* do nothing */}
-		public void appendGetNameMethodAnnotationTo(StringBuffer sb) {/* do nothing */}
-		public void appendSetNameMethodAnnotationTo(StringBuffer sb) {/* do nothing */}
-	}
-
-	public static class AnnotationWriterWrapper implements AnnotationWriter {
-		private final AnnotationWriter aw;
-		public AnnotationWriterWrapper(AnnotationWriter aw) {
-			super();
-			this.aw = aw;
-		}
-		public Iterator<String> imports() {return aw.imports();}
-		public void appendTypeAnnotationTo(StringBuffer sb) {aw.appendTypeAnnotationTo(sb);}
-		public void appendIdFieldAnnotationTo(StringBuffer sb) {aw.appendIdFieldAnnotationTo(sb);}
-		public void appendNameFieldAnnotationTo(StringBuffer sb) {aw.appendNameFieldAnnotationTo(sb);}
-		public void appendGetIdMethodAnnotationTo(StringBuffer sb) {aw.appendGetIdMethodAnnotationTo(sb);}
-		public void appendSetIdMethodAnnotationTo(StringBuffer sb) {aw.appendSetIdMethodAnnotationTo(sb);}
-		public void appendGetNameMethodAnnotationTo(StringBuffer sb) {aw.appendGetNameMethodAnnotationTo(sb);}
-		public void appendSetNameMethodAnnotationTo(StringBuffer sb) {aw.appendSetNameMethodAnnotationTo(sb);}
-	}
-
-	public class AnnotatedSourceWriter implements SourceWriter {
-		private AnnotationWriter annotationWriter;
-		public AnnotatedSourceWriter(AnnotationWriter annotationWriter) {
-			super();
-			this.annotationWriter = annotationWriter;
-		}
-		public void appendSourceTo(StringBuffer sb) {
-			AnnotationTestCase.this.appendSourceTo(sb, this.annotationWriter);
-		}
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/CombinationIndexedDeclarationAnnotationAdapterTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/CombinationIndexedDeclarationAnnotationAdapterTests.java
deleted file mode 100644
index 10a259c..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/CombinationIndexedDeclarationAnnotationAdapterTests.java
+++ /dev/null
@@ -1,728 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.MemberValuePair;
-import org.eclipse.jdt.core.dom.NormalAnnotation;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jpt.core.internal.jdtutility.AnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.CombinationIndexedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.IndexedAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.IndexedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.MemberAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.MemberIndexedAnnotationAdapter;
-
-public class CombinationIndexedDeclarationAnnotationAdapterTests extends AnnotationTestCase {
-
-	public CombinationIndexedDeclarationAnnotationAdapterTests(String name) {
-		super(name);
-	}
-
-	private void createAnnotationAndMembers(String annotationName, String annotationBody) throws Exception {
-		this.javaProject.createType("annot", annotationName + ".java", "public @interface " + annotationName + " { " + annotationBody + " }");
-	}
-
-	public void testGetAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumn(name=\"ADDRESS_ID\")");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.JoinColumn", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isNormalAnnotation());
-	}
-
-	public void testGetAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumn(name=\"ADDRESS_ID\")");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns(@annot.JoinColumn(name=\"ADDRESS_ID\"))");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.JoinColumn", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isNormalAnnotation());
-	}
-
-	public void testGetAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns(@annot.JoinColumn(name=\"ADDRESS_ID\"))");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.JoinColumn", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isNormalAnnotation());
-		String value = ((StringLiteral) ((MemberValuePair) ((NormalAnnotation) annotation).values().get(0)).getValue()).getLiteralValue();
-		assertEquals("ADDRESS_ID2", value);
-	}
-
-	public void testGetAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.JoinColumn", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isNormalAnnotation());
-		String value = ((StringLiteral) ((MemberValuePair) ((NormalAnnotation) annotation).values().get(0)).getValue()).getLiteralValue();
-		assertEquals("ADDRESS_ID2", value);
-	}
-
-	public void testGetAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testRemoveAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumn(name=\"ADDRESS_ID\")");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("JoinColumn");
-	}
-
-	public void testRemoveAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns(@annot.JoinColumn(name=\"ADDRESS_ID\"))");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("JoinColumns");
-		this.assertSourceDoesNotContain("JoinColumn");
-	}
-
-	public void testRemoveAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("JoinColumns");
-		this.assertSourceDoesNotContain("ADDRESS_ID2");
-		this.assertSourceContains("@JoinColumn(name=\"ADDRESS_ID1\")");
-	}
-
-	public void testRemoveAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("JoinColumns");
-		this.assertSourceDoesNotContain("ADDRESS_ID2");
-		this.assertSourceContains("@JoinColumn(name=\"ADDRESS_ID1\")");
-	}
-
-	public void testRemoveAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "String comment(); JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(comment=\"test\",columns={@annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.removeAnnotation();
-		this.assertSourceContains("@annot.JoinColumns(comment=\"test\",columns=@annot.JoinColumn(name=\"ADDRESS_ID1\"))");
-	}
-
-	public void testRemoveAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns(null)");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.removeAnnotation();
-		this.assertSourceContains("@annot.JoinColumns(null)");
-	}
-
-	public void testRemoveAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID0\")";
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(expected);
-		this.assertSourceDoesNotContain("JoinColumns");
-	}
-
-	public void testRemoveAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({null, @annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		this.assertSourceContains("@annot.JoinColumn");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("JoinColumn");
-	}
-
-	public void testRemoveAnnotation14() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\"), null})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID0\")";
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation15() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\"), @annot.JoinColumn(name=\"ADDRESS_ID3\")})");
-		String expected = "@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, null, @annot.JoinColumn(name=\"ADDRESS_ID3\")})";
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation16() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\"), @annot.JoinColumn(name=\"ADDRESS_ID3\")})");
-		String expected = "@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\")})";
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 3);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation17() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({null, null, @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		this.assertSourceContains("@annot.JoinColumn");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("JoinColumn");
-	}
-
-	public void testNewMarkerAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("JoinColumn");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("JoinColumn");
-		this.assertSourceDoesNotContain("JoinColumns");
-	}
-
-	public void testNewMarkerAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn");
-		this.assertSourceDoesNotContain("JoinColumns");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@JoinColumns(columns={@JoinColumn,@JoinColumn})");
-	}
-
-	public void testNewMarkerAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn, @annot.JoinColumn})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@annot.JoinColumns(columns={@annot.JoinColumn, @annot.JoinColumn," + CR + "    @JoinColumn})");
-	}
-
-	public void testNewMarkerAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn(77)");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("JoinColumn");
-		this.assertSourceDoesNotContain("JoinColumns");
-		this.assertSourceDoesNotContain("77");
-	}
-
-	public void testNewMarkerAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns=@annot.JoinColumn(77))");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 0);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@annot.JoinColumns(columns=@JoinColumn)");
-		this.assertSourceDoesNotContain("77");
-	}
-
-	public void testNewMarkerAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns=@annot.JoinColumn(77))");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@annot.JoinColumns(columns={@annot.JoinColumn(77),@JoinColumn})");
-	}
-
-	public void testNewMarkerAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn(77)");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@JoinColumns(columns={@JoinColumn(77),@JoinColumn})");
-	}
-
-	public void testNewMarkerAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(77),@annot.JoinColumn(88)})");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@annot.JoinColumns(columns={@annot.JoinColumn(77),@JoinColumn})");
-	}
-
-	public void testNewMarkerAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name(); String text(); int num();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn(text=\"blah\",num=42)");
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@JoinColumns(columns={@JoinColumn(text=\"blah\", num=42),@JoinColumn})");
-	}
-
-	public void testNewMarkerAnnotation23() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name(); String text(); int num();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn(text=\"blah\",num=42)");
-		String expected = "@JoinColumns(columns={@JoinColumn(text=\"blah\", num=42),null,@JoinColumn})";
-		this.assertSourceDoesNotContain(expected);
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation24() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name(); String text(); int num();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumn(text=\"blah\",num=42)");
-		String expected1 = "@JoinColumns({";
-		String expected2 = "@JoinColumn(text=\"blah\", num=42),null,";
-		String expected3 = "@JoinColumn})";
-		this.assertSourceDoesNotContain(expected1);
-		this.assertSourceDoesNotContain(expected2);
-		this.assertSourceDoesNotContain(expected3);
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 2);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected1);
-		this.assertSourceContains(expected2);
-		this.assertSourceContains(expected3);
-	}
-
-	public void testNewMarkerAnnotation25() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		String expected1 = "@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), null, null,";  // the line gets split
-		String expected2 = "@JoinColumn})";
-		this.assertSourceDoesNotContain(expected1);
-		this.assertSourceDoesNotContain(expected2);
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 4);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected1);
-		this.assertSourceContains(expected2);
-	}
-
-	public void testNewMarkerAnnotation26() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		String expected1 = "@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), null, null,";  // the line gets split
-		String expected2 = "@JoinColumn})";
-		this.assertSourceDoesNotContain(expected1);
-		this.assertSourceDoesNotContain(expected2);
-		DeclarationAnnotationAdapter daa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 4);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected1);
-		this.assertSourceContains(expected2);
-	}
-
-	public void testMoveAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn(name=\"ADDRESS_ID0\")");
-		String expected = "@JoinColumns(columns={null,@JoinColumn(name=\"ADDRESS_ID0\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 0);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(1);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={null,@annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID1\")";
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-		this.assertSourceDoesNotContain("JoinColumns");
-	}
-
-	public void testMoveAnnotation2a() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({null,@annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID1\")";
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 1);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-		this.assertSourceDoesNotContain("JoinColumns");
-	}
-
-	public void testMoveAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\"), @annot.JoinColumn(name=\"ADDRESS_ID3\")})");
-		String expected = "@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID3\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 3);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\"), @annot.JoinColumn(name=\"ADDRESS_ID3\"), @annot.JoinColumn(name=\"ADDRESS_ID4\")})");
-		String expected = "@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID3\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\"), null, @annot.JoinColumn(name=\"ADDRESS_ID4\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 3);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		String expected = "@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 2);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(3);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		String expected = "@annot.JoinColumns(columns={null, @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\"), @annot.JoinColumn(name=\"ADDRESS_ID0\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 0);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(3);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		String expected = "@annot.JoinColumns(columns={null, @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 3);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\"), null, @annot.JoinColumn(name=\"ADDRESS_ID4\")})");
-		String expected = "@annot.JoinColumns(columns={null, @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\"), null, @annot.JoinColumn(name=\"ADDRESS_ID4\")})";
-		this.assertSourceDoesNotContain(expected);
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 3);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		String expected = "@annot.JoinColumns(columns={null, @annot.JoinColumn(name=\"ADDRESS_ID1\"), @annot.JoinColumn(name=\"ADDRESS_ID2\")})";
-		this.createTestType(expected);  // the source should be unchanged
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 0);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(3);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation10() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID0\")";
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 2);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(1);
-		this.assertSourceContains(expected);
-		this.assertSourceDoesNotContain("@annot.JoinColumns");
-	}
-
-	public void testMoveAnnotation10a() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] value();");
-		this.createTestType("@annot.JoinColumns({@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\")})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID0\")";
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "value", 2);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(1);
-		this.assertSourceContains(expected);
-		this.assertSourceDoesNotContain("@annot.JoinColumns");
-	}
-
-	public void testMoveAnnotation11() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumn(name=\"ADDRESS_ID0\")");
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 1);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceDoesNotContain("JoinColumn");
-	}
-
-	public void testMoveAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), null, @annot.JoinColumn(name=\"ADDRESS_ID2\")})");
-		String expected = "@JoinColumn(name=\"ADDRESS_ID2\")";
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 2);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-		this.assertSourceDoesNotContain("@annot.JoinColumns");
-	}
-
-	public void testMoveAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("JoinColumn", "String name();");
-		this.createAnnotationAndMembers("JoinColumns", "JoinColumn[] columns();");
-		this.createTestType("@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID0\"), @annot.JoinColumn(name=\"ADDRESS_ID1\"), null, @annot.JoinColumn(name=\"ADDRESS_ID3\")})");
-		String expected = "@annot.JoinColumns(columns={@annot.JoinColumn(name=\"ADDRESS_ID3\"), @annot.JoinColumn(name=\"ADDRESS_ID1\")})";
-		IndexedDeclarationAnnotationAdapter cidaa = new CombinationIndexedDeclarationAnnotationAdapter(
-				"annot.JoinColumn", "annot.JoinColumns", "columns", 3);
-		IndexedAnnotationAdapter iaa  = new MemberIndexedAnnotationAdapter(this.idField(), cidaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/JDTToolsTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/JDTToolsTests.java
deleted file mode 100644
index 706e606..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/JDTToolsTests.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import org.eclipse.jdt.core.dom.Name;
-import org.eclipse.jpt.core.internal.jdtutility.ConversionDeclarationAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.FieldAttribute;
-import org.eclipse.jpt.core.internal.jdtutility.JDTTools;
-import org.eclipse.jpt.core.internal.jdtutility.SimpleDeclarationAnnotationAdapter;
-
-public class JDTToolsTests extends AnnotationTestCase {
-
-	public JDTToolsTests(String name) {
-		super(name);
-	}
-
-	private void createEnumAndMembers(String enumName, String enumBody) throws Exception {
-		this.javaProject.createType("enums", enumName + ".java", "public enum " + enumName + " { " + enumBody + " }");
-	}
-
-	private void createAnnotationAndMembers(String annotationName, String annotationBody) throws Exception {
-		this.javaProject.createType("annot", annotationName + ".java", "public @interface " + annotationName + " { " + annotationBody + " }");
-	}
-
-	public void testResolveEnum1() throws Exception {
-		this.createEnumAndMembers("TestEnum", "FOO, BAR, BAZ");
-		this.createAnnotationAndMembers("TestAnnotation", "TestEnum foo();");
-
-		this.createTestType("@annot.TestAnnotation(foo=enums.TestEnum.BAZ)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.TestAnnotation");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "foo");
-		FieldAttribute field = this.idField();
-
-		String actual = JDTTools.resolveEnum((Name) field.annotationElementExpression(daea));
-		assertEquals("enums.TestEnum.BAZ", actual);
-	}
-
-	public void testResolveEnum2() throws Exception {
-		this.createEnumAndMembers("TestEnum", "FOO, BAR, BAZ");
-		this.createAnnotationAndMembers("TestAnnotation", "TestEnum foo();");
-
-		this.createTestType("static enums.TestEnum.BAZ", "@annot.TestAnnotation(foo=BAZ)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.TestAnnotation");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "foo");
-		FieldAttribute field = this.idField();
-
-		String actual = JDTTools.resolveEnum((Name) field.annotationElementExpression(daea));
-		assertEquals("enums.TestEnum.BAZ", actual);
-	}
-
-	public void testResolveEnum3() throws Exception {
-		this.createEnumAndMembers("TestEnum", "FOO, BAR, BAZ");
-		this.createAnnotationAndMembers("TestAnnotation", "TestEnum foo();");
-
-		this.createTestType("static enums.TestEnum.*", "@annot.TestAnnotation(foo=BAZ)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.TestAnnotation");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "foo");
-		FieldAttribute field = this.idField();
-
-		String actual = JDTTools.resolveEnum((Name) field.annotationElementExpression(daea));
-		assertEquals("enums.TestEnum.BAZ", actual);
-	}
-
-	public void testResolveEnum4() throws Exception {
-		this.createEnumAndMembers("TestEnum", "FOO, BAR, BAZ");
-		this.createAnnotationAndMembers("TestAnnotation", "TestEnum foo();");
-
-		this.createTestType("enums.TestEnum", "@annot.TestAnnotation(foo=TestEnum.BAZ)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.TestAnnotation");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "foo");
-		FieldAttribute field = this.idField();
-
-		String actual = JDTTools.resolveEnum((Name) field.annotationElementExpression(daea));
-		assertEquals("enums.TestEnum.BAZ", actual);
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/JptCoreJdtUtilityTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/JptCoreJdtUtilityTests.java
deleted file mode 100644
index a6a0fb6..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/JptCoreJdtUtilityTests.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class JptCoreJdtUtilityTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(JptCoreJdtUtilityTests.class.getName());
-		suite.addTestSuite(MemberAnnotationElementAdapterTests.class);
-		suite.addTestSuite(CombinationIndexedDeclarationAnnotationAdapterTests.class);
-		suite.addTestSuite(JDTToolsTests.class);
-		suite.addTestSuite(NestedDeclarationAnnotationAdapterTests.class);
-		suite.addTestSuite(NestedIndexedDeclarationAnnotationAdapterTests.class);
-		suite.addTestSuite(SimpleDeclarationAnnotationAdapterTests.class);
-		suite.addTestSuite(TypeTests.class);
-		return suite;
-	}
-
-	private JptCoreJdtUtilityTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/MemberAnnotationElementAdapterTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/MemberAnnotationElementAdapterTests.java
deleted file mode 100644
index b07c314..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/MemberAnnotationElementAdapterTests.java
+++ /dev/null
@@ -1,948 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import java.util.Arrays;
-
-import org.eclipse.jpt.core.internal.ITextRange;
-import org.eclipse.jpt.core.internal.jdtutility.ASTNodeTextRange;
-import org.eclipse.jpt.core.internal.jdtutility.AnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.AnnotationStringArrayExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.BooleanStringExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.CharacterStringExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.ConversionDeclarationAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.EnumArrayDeclarationAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.EnumDeclarationAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.ExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.MemberAnnotationElementAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.NestedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.NestedIndexedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.NumberStringExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.PrimitiveTypeStringExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.SimpleDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.SimpleTypeStringExpressionConverter;
-import org.eclipse.jpt.core.internal.jdtutility.StringExpressionConverter;
-
-public class MemberAnnotationElementAdapterTests extends AnnotationTestCase {
-
-	public MemberAnnotationElementAdapterTests(String name) {
-		super(name);
-	}
-
-	private void createAnnotationAndMembers(String annotationName, String annotationBody) throws Exception {
-		this.javaProject.createType("annot", annotationName + ".java", "public @interface " + annotationName + " { " + annotationBody + " }");
-	}
-
-	private void createEnum(String enumName, String enumBody) throws Exception {
-		this.javaProject.createType("enums", enumName + ".java", "public enum " + enumName + " { " + enumBody + " }");
-	}
-
-	public void testGetValue1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType("@annot.Foo(bar=\"xxx\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("xxx", aea.getValue());
-	}
-
-	public void testGetValue2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "int bar();");
-		this.createTestType("@annot.Foo(bar=48)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", NumberStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("48", aea.getValue());
-	}
-
-	public void testGetValue3() throws Exception {
-		this.createAnnotationAndMembers("Foo", "char bar();");
-		this.createTestType("@annot.Foo(bar='c')");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", CharacterStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("c", aea.getValue());
-	}
-
-	public void testGetValue4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean bar();");
-		this.createTestType("@annot.Foo(bar=false)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-	}
-
-	public void testGetValue5() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType("@annot.Foo(@annot.Bar(jimmy=@annot.Baz(fred=false)))");
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-	}
-
-	public void testGetValue6() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean value();");
-		this.createTestType("@annot.Foo(false)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-	}
-
-	public void testGetValueNull1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType("@annot.Foo");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueNull2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueNull3() throws Exception {
-		this.createAnnotationAndMembers("Baz", "String fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType("@annot.Foo(@annot.Bar(jimmy=@annot.Baz))");
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa3, "fred");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueStringConcatenation() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType("@annot.Foo(bar=\"xxx\" + \"yyy\" + \"zzz\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("xxxyyyzzz", aea.getValue());
-	}
-
-	public void testGetValueStringConstant() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		// just a bit hacky:
-		this.createTestType("private static final String FOO_BAR = \"xxx\"; @annot.Foo(bar=FOO_BAR + \"yyy\" + \"zzz\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("xxxyyyzzz", aea.getValue());
-	}
-
-	public void testGetValueNumberArithmetic() throws Exception {
-		this.createAnnotationAndMembers("Foo", "int bar();");
-		this.createTestType("@annot.Foo(bar=47 - 7 + 2 * 1 / 1)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forNumbers(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("42", aea.getValue());
-	}
-
-	public void testGetValueNumberShift() throws Exception {
-		this.createAnnotationAndMembers("Foo", "int bar();");
-		this.createTestType("@annot.Foo(bar=2 << 2)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forNumbers(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("8", aea.getValue());
-	}
-
-	public void testGetValueNumberConstant() throws Exception {
-		this.createAnnotationAndMembers("Foo", "int bar();");
-		// just a bit hacky:
-		this.createTestType("private static final int FOO_BAR = 77; @annot.Foo(bar=FOO_BAR)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forNumbers(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("77", aea.getValue());
-	}
-
-	public void testGetValueCharacterConstant() throws Exception {
-		this.createAnnotationAndMembers("Foo", "char bar();");
-		// just a bit hacky:
-		this.createTestType("private static final char FOO_BAR = 'Q'; @annot.Foo(bar=FOO_BAR)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forCharacters(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("Q", aea.getValue());
-	}
-
-	public void testGetValueCharacterCast() throws Exception {
-		this.createAnnotationAndMembers("Foo", "char bar();");
-		this.createTestType("@annot.Foo(bar=(char) 0x41)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forCharacters(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("A", aea.getValue());
-	}
-
-	public void testGetValueBooleanOperator1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean bar();");
-		this.createTestType("@annot.Foo(bar=7 > 2)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forBooleans(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("true", aea.getValue());
-	}
-
-	public void testGetValueBooleanOperator2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean bar();");
-		this.createTestType("@annot.Foo(bar=7 == 2)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forBooleans(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-	}
-
-	public void testGetValueBooleanOperator3() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean bar();");
-		this.createTestType("@annot.Foo(bar=(7 != 2) && false)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forBooleans(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-	}
-
-	public void testGetValueBooleanOperator4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean bar();");
-		this.createTestType("@annot.Foo(bar=(7 != 2) ? false : true)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forBooleans(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-	}
-
-	public void testGetValueInvalidValue1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType("@annot.Foo(bar=77)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType("@annot.Foo(bar=bazzzz)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue3() throws Exception {
-		this.createAnnotationAndMembers("Foo", "boolean bar();");
-		this.createTestType("@annot.Foo(bar=bazzzz)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forBooleans(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "char bar();");
-		this.createTestType("@annot.Foo(bar=\"bazzzz\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forCharacters(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue5() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=\"java.lang.Object\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", SimpleTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue6() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		this.createTestType("@annot.Foo(bar=enums.TestEnum.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue7() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		String value = "\"false\"";
-		String element = "fred=" + value;
-		String annotation = "@annot.Foo(@annot.Bar(jimmy=@annot.Baz(" + element + ")))";
-		this.createTestType(annotation);
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueInvalidValue8() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo(bar={true, false})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {null, null}, aea.getValue()));
-	}
-
-	public void testGetValueInvalidValue9() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo(bar=77)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {null}, aea.getValue()));
-	}
-
-	public void testASTNode1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		String value = "\"xxx\"";
-		String element = "bar=" + value;
-		String annotation = "@annot.Foo(" + element + ")";
-		this.createTestType(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		ITextRange textRange = new ASTNodeTextRange(aea.astNode());
-		assertEquals(this.source().indexOf(value), textRange.getOffset());
-		assertEquals(value.length(), textRange.getLength());
-		assertEquals(7, textRange.getLineNumber());
-	}
-
-	public void testASTNode2() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		String value = "false";
-		String element = "fred=" + value;
-		String annotation = "@annot.Foo(@annot.Bar(jimmy=@annot.Baz(" + element + ")))";
-		this.createTestType(annotation);
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("false", aea.getValue());
-		ITextRange textRange = new ASTNodeTextRange(aea.astNode());
-		assertEquals(value.length(), textRange.getLength());
-	}
-
-	public void testASTNode3() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String value();");
-		String element = "\"xxx\"";
-		String annotation = "@annot.Foo(" + element + ")";
-		this.createTestType(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa);
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		ITextRange textRange = new ASTNodeTextRange(aea.astNode());
-		assertEquals(this.source().indexOf(element), textRange.getOffset());
-		assertEquals(element.length(), textRange.getLength());
-	}
-
-	public void testASTNode4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String value();");
-		String annotation = "@annot.Foo";
-		this.createTestType(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa);
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		ITextRange textRange = new ASTNodeTextRange(aea.astNode());
-		assertEquals(this.source().indexOf(annotation), textRange.getOffset());
-		assertEquals(annotation.length(), textRange.getLength());
-	}
-
-	public void testSetValue1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		String annotation = "@annot.Foo(bar=\"xxx\")";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue(null);
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testSetValue2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		String annotation = "@annot.Foo(bar=\"xxx\")";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar", false);
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue(null);
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@Foo");
-	}
-
-	public void testSetValue3() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		String annotation = "@annot.Foo(@annot.Bar(jimmy=@annot.Baz(fred=false)))";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue(null);
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceDoesNotContain("Foo");
-		this.assertSourceDoesNotContain("Bar");
-	}
-
-	public void testSetValue3a() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		String annotation = "@annot.Foo(@annot.Bar(jimmy=@annot.Baz(fred=false)))";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar", false);
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz", false);
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue(null);
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@annot.Foo(@Bar)");
-	}
-
-	public void testSetValue4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("xxx");
-		this.assertSourceContains("@Foo(bar=\"xxx\")");
-	}
-
-	public void testSetValue5() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		String annotation = "@annot.Foo(@annot.Bar(jimmy=@annot.Baz(fred=false)))";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("true");
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@annot.Foo(@annot.Bar(jimmy=@annot.Baz(fred=true)))");
-	}
-
-	public void testSetValue6() throws Exception {
-		this.createAnnotationAndMembers("Baz", "boolean fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "jimmy", "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", BooleanStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("true");
-		this.assertSourceContains("@Foo(@Bar(jimmy=@Baz(fred=true)))");
-	}
-
-	public void testSetValue7() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		String annotation = "@annot.Foo(bar=\"xxx\")";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("yyy");
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@annot.Foo(bar=\"yyy\")");
-	}
-
-	public void testSetValue8() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar();");
-		String annotation = "@annot.Foo";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("xxx");
-		this.assertSourceContains("@Foo(bar=\"xxx\")");
-	}
-
-	public void testSetValue9() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String value(); String bar();");
-		String annotation = "@annot.Foo(\"zzz\")";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("xxx");
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@Foo(value=\"zzz\", bar=\"xxx\")");
-	}
-
-	public void testSetValue10() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String bar(); String baz();");
-		String annotation = "@annot.Foo(bar=\"xxx\")";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "baz");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("yyy");
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@annot.Foo(bar=\"xxx\", baz = \"yyy\")");
-	}
-
-	public void testSetValue11() throws Exception {
-		this.createAnnotationAndMembers("Baz", "int fred();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz[] jimmy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		String annotation = "@annot.Foo(@annot.Bar(jimmy={@annot.Baz(fred=0), @annot.Baz(fred=1), @annot.Baz(fred=2), @annot.Baz(fred=3)}))";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "value", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedIndexedDeclarationAnnotationAdapter(daa2, "jimmy", 2, "annot.Baz");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa3, "fred", NumberStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		assertEquals("2", aea.getValue());
-		aea.setValue("48");
-		this.assertSourceContains("@annot.Foo(@annot.Bar(jimmy={@annot.Baz(fred=0), @annot.Baz(fred=1), @annot.Baz(fred=48), @annot.Baz(fred=3)}))");
-	}
-
-	public void testSetValue12() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String value();");
-		String annotation = "@annot.Foo";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "value");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("xxx");
-		this.assertSourceContains("@Foo(\"xxx\")");
-	}
-
-	public void testSetValue13() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String value();");
-		String annotation = "@annot.Foo(\"zzz\")";
-		this.createTestType(annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = ConversionDeclarationAnnotationElementAdapter.forStrings(daa, "value");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-
-		aea.setValue("xxx");
-		this.assertSourceDoesNotContain(annotation);
-		this.assertSourceContains("@annot.Foo(\"xxx\")");
-	}
-
-	public void testSimpleTypeLiteral1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=java.lang.Object.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", SimpleTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("java.lang.Object", aea.getValue());
-	}
-
-	public void testSimpleTypeLiteral2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", SimpleTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		aea.setValue("java.lang.Object");
-		this.assertSourceContains("@Foo(bar=java.lang.Object.class)");
-	}
-
-	public void testSimpleTypeLiteral3() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=int.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", SimpleTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testSimpleTypeLiteral4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=java.util.Map.Entry.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", SimpleTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("java.util.Map.Entry", aea.getValue());
-	}
-
-	public void testPrimitiveTypeLiteral1() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=int.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", PrimitiveTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("int", aea.getValue());
-	}
-
-	public void testPrimitiveTypeLiteral2() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", PrimitiveTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		aea.setValue("int");
-		this.assertSourceContains("@Foo(bar=int.class)");
-	}
-
-	public void testPrimitiveTypeLiteral3() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=java.lang.Object.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", PrimitiveTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testPrimitiveTypeLiteral4() throws Exception {
-		this.createAnnotationAndMembers("Foo", "Class bar();");
-		this.createTestType("@annot.Foo(bar=void.class)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new ConversionDeclarationAnnotationElementAdapter<String>(daa, "bar", PrimitiveTypeStringExpressionConverter.instance());
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("void", aea.getValue());
-	}
-
-	public void testGetValueEnum1() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		this.createTestType("@annot.Foo(bar=enums.TestEnum.XXX)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("enums.TestEnum.XXX", aea.getValue());
-	}
-
-	public void testGetValueEnum2() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		this.createTestType("static enums.TestEnum.XXX", "@annot.Foo(bar=XXX)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("enums.TestEnum.XXX", aea.getValue());
-	}
-
-	public void testGetValueEnum3() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		this.createTestType("@annot.Foo");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertNull(aea.getValue());
-	}
-
-	public void testGetValueEnum4() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		this.createTestType("enums.TestEnum", "@annot.Foo(bar=TestEnum.XXX)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		assertEquals("enums.TestEnum.XXX", aea.getValue());
-	}
-
-	public void testSetValueEnum1() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		String annotation = "@annot.Foo(bar=XXX)";
-		this.createTestType("static enums.TestEnum.XXX", annotation);
-		this.assertSourceContains(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		aea.setValue(null);
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testSetValueEnum2() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum bar();");
-		String annotation = "@Foo(bar=XXX)";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String> daea = new EnumDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String> aea = new MemberAnnotationElementAdapter<String>(this.idField(), daea);
-		aea.setValue("enums.TestEnum.XXX");
-		this.assertSourceContains("import static enums.TestEnum.XXX;");
-		this.assertSourceContains(annotation);
-	}
-
-	public void testGetValueStringArray() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo(bar={\"string0\", \"string1\"})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {"string0", "string1"}, aea.getValue()));
-	}
-
-	public void testGetValueStringArrayConcatenation() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo(bar={\"stri\" + \"ng0\", \"s\" + \"tring1\"})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {"string0", "string1"}, aea.getValue()));
-	}
-
-	public void testGetValueStringArrayEmpty() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo(bar={})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[0], aea.getValue()));
-	}
-
-	public void testGetValueStringArraySingleElement() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo(bar=\"string0\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {"string0"}, aea.getValue()));
-	}
-
-	public void testGetValueNullStringArray() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		this.createTestType("@annot.Foo()");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[0], aea.getValue()));
-	}
-
-	public void testSetValueStringArray() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		String annotation = "@Foo(bar={\"string0\",\"string1\"})";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[] {"string0", "string1"});
-		this.assertSourceContains(annotation);
-	}
-
-	public void testSetValueStringArrayEmptyRemove() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		String annotation = "@Foo";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[0]);
-		this.assertSourceDoesNotContain(annotation);
-	}
-
-	public void testSetValueStringArrayEmpty() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		String annotation = "@Foo(bar={})";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		ExpressionConverter<String[]> expressionConverter = new AnnotationStringArrayExpressionConverter(StringExpressionConverter.instance(), false);
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", expressionConverter);
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[0]);
-		this.assertSourceContains(annotation);
-	}
-
-	public void testSetValueStringArraySingleElement() throws Exception {
-		this.createAnnotationAndMembers("Foo", "String[] bar();");
-		String annotation = "@Foo(bar=\"string0\")";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new ConversionDeclarationAnnotationElementAdapter<String[]>(daa, "bar", AnnotationStringArrayExpressionConverter.forStrings());
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[] {"string0"});
-		this.assertSourceContains(annotation);
-	}
-
-	public void testGetValueEnumArray() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		this.createTestType("@annot.Foo(bar={enums.TestEnum.XXX, enums.TestEnum.YYY})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {"enums.TestEnum.XXX", "enums.TestEnum.YYY"}, aea.getValue()));
-	}
-
-	public void testGetValueEnumArrayInvalidEntry() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		this.createTestType("@annot.Foo(bar={enums.TestEnum.XXX, 88})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {"enums.TestEnum.XXX", null}, aea.getValue()));
-	}
-
-	public void testGetValueEnumArrayEmpty() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		this.createTestType("@annot.Foo(bar={})");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[0], aea.getValue()));
-	}
-
-	public void testGetValueEnumArraySingleElement() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		this.createTestType("@annot.Foo(bar=enums.TestEnum.XXX)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {"enums.TestEnum.XXX"}, aea.getValue()));
-	}
-
-	public void testGetValueEnumArraySingleElementInvalid() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		this.createTestType("@annot.Foo(bar=\"\")");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[] {null}, aea.getValue()));
-	}
-
-	public void testGetValueNullEnumArray() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		this.createTestType("@annot.Foo()");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		assertTrue(Arrays.equals(new String[0], aea.getValue()));
-	}
-
-	public void testSetValueEnumArray() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		String annotation = "@Foo(bar={XXX,YYY})";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[] {"enums.TestEnum.XXX", "enums.TestEnum.YYY"});
-		this.assertSourceContains("import static enums.TestEnum.XXX;");
-		this.assertSourceContains("import static enums.TestEnum.YYY;");
-		this.assertSourceContains(annotation);
-	}
-
-	public void testSetValueEnumArrayEmptyRemove() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		String annotation = "@Foo";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[0]);
-		this.assertSourceDoesNotContain(annotation);
-	}
-
-	public void testSetValueEnumArrayEmpty() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		String annotation = "@Foo(bar={})";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar", true, false);
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[0]);
-		this.assertSourceContains(annotation);
-	}
-
-	public void testSetValueEnumArraySingleElement() throws Exception {
-		this.createEnum("TestEnum", "XXX, YYY, ZZZ");
-		this.createAnnotationAndMembers("Foo", "enums.TestEnum[] bar();");
-		String annotation = "@Foo(bar=XXX)";
-		this.createTestType();
-		this.assertSourceDoesNotContain(annotation);
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationElementAdapter<String[]> daea = new EnumArrayDeclarationAnnotationElementAdapter(daa, "bar");
-		AnnotationElementAdapter<String[]> aea = new MemberAnnotationElementAdapter<String[]>(this.idField(), daea);
-		aea.setValue(new String[] {"enums.TestEnum.XXX"});
-		this.assertSourceContains("import static enums.TestEnum.XXX;");
-		this.assertSourceContains(annotation);
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/NestedDeclarationAnnotationAdapterTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/NestedDeclarationAnnotationAdapterTests.java
deleted file mode 100644
index e82d42c..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/NestedDeclarationAnnotationAdapterTests.java
+++ /dev/null
@@ -1,763 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.NormalAnnotation;
-import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jpt.core.internal.jdtutility.AnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.Member;
-import org.eclipse.jpt.core.internal.jdtutility.MemberAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.ModifiedDeclaration;
-import org.eclipse.jpt.core.internal.jdtutility.NestedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.SimpleDeclarationAnnotationAdapter;
-
-public class NestedDeclarationAnnotationAdapterTests extends AnnotationTestCase {
-
-	public NestedDeclarationAnnotationAdapterTests(String name) {
-		super(name);
-	}
-
-	private void createAnnotationAndMembers(String annotationName, String annotationBody) throws Exception {
-		this.javaProject.createType("annot", annotationName + ".java", "public @interface " + annotationName + " { " + annotationBody + " }");
-	}
-
-	public void testGetAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo(nestedAnnotation=@annot.Bar)");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Bar", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-	}
-
-	public void testGetAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Baz", "String value();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz yana();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo(nestedAnnotation=@annot.Bar(yana=@annot.Baz))");
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedDeclarationAnnotationAdapter(daa1, "nestedAnnotation", "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedDeclarationAnnotationAdapter(daa2, "yana", "annot.Baz");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa3);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Baz", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-	}
-
-	public void testGetAnnotationNull1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo()");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType();
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "String nestedAnnotation();");
-		this.createTestType("@annot.Foo(nestedAnnotation=\"annot.Bar\")");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Bar2", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar2 nestedAnnotation();");
-		this.createTestType("@annot.Foo(nestedAnnotation=@annot.Bar2)");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testRemoveAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		String na = "@annot.Foo(nestedAnnotation=@annot.Bar)";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testRemoveAnnotation1a() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		String na = "@annot.Foo(nestedAnnotation=@annot.Bar)";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar", false);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains("Foo");
-	}
-
-	public void testRemoveAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testRemoveAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "String nestedAnnotation();");
-		String na = "@annot.Foo(nestedAnnotation=\"annot.Bar\")";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(na);
-	}
-
-	public void testRemoveAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Bar2", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar2 nestedAnnotation();");
-		String na = "@annot.Foo(nestedAnnotation=@annot.Bar2)";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(na);
-	}
-
-	public void testRemoveAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Baz", "String value();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz nestedAnnotation2();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation1();");
-		String na = "@annot.Foo(nestedAnnotation1=@annot.Bar(nestedAnnotation2=@annot.Baz))";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daaFoo = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daaBar = new NestedDeclarationAnnotationAdapter(daaFoo, "nestedAnnotation1", "annot.Bar");
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(daaBar, "nestedAnnotation2", "annot.Baz");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceDoesNotContain("Foo");
-		this.assertSourceDoesNotContain("Bar");
-		this.assertSourceDoesNotContain("Baz");
-	}
-
-	public void testRemoveAnnotation5a() throws Exception {
-		this.createAnnotationAndMembers("Baz", "String value();");
-		this.createAnnotationAndMembers("Bar", "annot.Baz nestedAnnotation2();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation1();");
-		String na = "@annot.Foo(nestedAnnotation1=@annot.Bar(nestedAnnotation2=@annot.Baz))";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daaFoo = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daaBar = new NestedDeclarationAnnotationAdapter(daaFoo, "nestedAnnotation1", "annot.Bar", false);
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(daaBar, "nestedAnnotation2", "annot.Baz", false);
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains("@annot.Foo(nestedAnnotation1=@Bar)");
-	}
-
-	public void testNewMarkerAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@Foo(nestedAnnotation=@Bar)");
-	}
-
-	public void testNewMarkerAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@Foo(@Bar)");
-	}
-
-	public void testNewMarkerAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(nestedAnnotation=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation(); String value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@Foo(value=\"something\", nestedAnnotation=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "Object value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@annot.Foo(@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", nestedAnnotation = @Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar value();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", value = @Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewSingleMemberAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation1(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(nestedAnnotation=@Bar(\"test string literal\"))");
-	}
-
-	void editNewSingleMemberAnnotation1(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) aa.getAnnotation();
-		assertNull(annotation);
-
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation2(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(@Bar(\"test string literal\"))");
-	}
-
-	void editNewSingleMemberAnnotation2(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(nestedAnnotation=@Bar(\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation3(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation3(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(@Bar(\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation4(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation4(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation(); String value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@Foo(value=\"something\", nestedAnnotation=@Bar(\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation5(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation5(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "Object value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@annot.Foo(@Bar(\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation6(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation6(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation(); String xxx();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", nestedAnnotation = @Bar(\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation7(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation7(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value(); String xxx();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", value = @Bar(\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation8(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation8(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewNormalAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation1(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(nestedAnnotation=@Bar(yyy=\"test string literal\"))");
-	}
-
-	void editNewNormalAnnotation1(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation2(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(@Bar(yyy=\"test string literal\"))");
-	}
-
-	void editNewNormalAnnotation2(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(nestedAnnotation=@Bar(yyy=\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation3(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation3(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar value();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(@Bar(yyy=\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation4(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation4(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar nestedAnnotation(); String value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@Foo(value=\"something\", nestedAnnotation=@Bar(yyy=\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation5(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation5(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "Object value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@annot.Foo(@Bar(yyy=\"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation6(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation6(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar nestedAnnotation();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", nestedAnnotation = @Bar(yyy = \"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation7(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation7(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotation", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-	public void testNewNormalAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String yyy();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar value();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", value = @Bar(yyy = \"test string literal\"))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation8(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation8(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "yyy", "test string literal");
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/NestedIndexedDeclarationAnnotationAdapterTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/NestedIndexedDeclarationAnnotationAdapterTests.java
deleted file mode 100644
index e361b43..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/NestedIndexedDeclarationAnnotationAdapterTests.java
+++ /dev/null
@@ -1,2209 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.NormalAnnotation;
-import org.eclipse.jdt.core.dom.NumberLiteral;
-import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
-import org.eclipse.jpt.core.internal.jdtutility.AnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.IndexedAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.IndexedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.Member;
-import org.eclipse.jpt.core.internal.jdtutility.MemberAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.MemberIndexedAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.ModifiedDeclaration;
-import org.eclipse.jpt.core.internal.jdtutility.NestedIndexedDeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.SimpleDeclarationAnnotationAdapter;
-
-public class NestedIndexedDeclarationAnnotationAdapterTests extends AnnotationTestCase {
-
-	public NestedIndexedDeclarationAnnotationAdapterTests(String name) {
-		super(name);
-	}
-
-	private void createAnnotation(String annotationName) throws Exception {
-		this.createAnnotationAndMembers(annotationName, "");
-	}
-
-	private void createAnnotationAndMembers(String annotationName, String annotationBody) throws Exception {
-		this.javaProject.createType("annot", annotationName + ".java", "public @interface " + annotationName + " { " + annotationBody + " }");
-	}
-
-	public void testGetAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={@annot.Bar, @annot.Bar(\"two\")})");
-		// 0
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Bar", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-
-		// 1
-		daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 1, "annot.Bar");
-		aa = new MemberAnnotationAdapter(this.idField(), daa);
-		annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Bar", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isSingleMemberAnnotation());
-	}
-
-	public void testGetAnnotation2() throws Exception {
-		this.createAnnotation("Baz");
-		this.createAnnotationAndMembers("Bar", "annot.Baz[] yana();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(yana=@annot.Baz))");
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 0, "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedIndexedDeclarationAnnotationAdapter(daa2, "yana", 0, "annot.Baz");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa3);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Baz", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-	}
-
-	public void testGetAnnotation3() throws Exception {
-		this.createAnnotation("Baz");
-		this.createAnnotationAndMembers("Bar", "annot.Baz[] yana();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(yana={@annot.Baz}))");
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 0, "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedIndexedDeclarationAnnotationAdapter(daa2, "yana", 0, "annot.Baz");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa3);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Baz", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-
-		// name mismatch
-		daa3 = new NestedIndexedDeclarationAnnotationAdapter(daa2, "yana", 0, "annot.Xyz");
-		aa = new MemberAnnotationAdapter(this.idField(), daa3);
-		annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull1() throws Exception {
-		this.createAnnotation("Bar");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo()");
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull2() throws Exception {
-		this.createAnnotation("Bar");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull3() throws Exception {
-		this.createAnnotation("Bar");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=\"annot.Bar\")");
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull4() throws Exception {
-		this.createAnnotation("NotBar");
-		this.createAnnotation("Bar");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "String value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={@annot.Bar, @annot.Bar(\"two\")})");
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 2, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull6() throws Exception {
-		this.createAnnotation("Xyz");
-		this.createAnnotation("Baz");
-		this.createAnnotationAndMembers("Bar", "annot.Baz[] yana();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(yana={@annot.Baz}))");
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 0, "annot.Bar");
-		DeclarationAnnotationAdapter daa3 = new NestedIndexedDeclarationAnnotationAdapter(daa2, "yana", 0, "annot.Xyz");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa3);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testRemoveAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.Bar(0), @annot.Bar(1)})";
-		String expected = "@annot.Foo(nestedAnnotations={null, @annot.Bar(1)})";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testRemoveAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={\"annot.Bar1\", \"annot.Bar2\", \"annot.Bar3\"})";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(na);
-	}
-
-	public void testRemoveAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.NotBar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.NotBar(0), @annot.NotBar(1)})";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(na);
-	}
-
-	public void testRemoveAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations=@annot.Bar)";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		assertNull(aa.getAnnotation());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testRemoveAnnotation5a() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations=@annot.Bar)";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 0, "annot.Bar", false);
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertTrue(aa1.getAnnotation().isMarkerAnnotation());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains("import annot.Foo;");
-		this.assertSourceContains("@Foo");
-	}
-
-	public void testRemoveAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations=\"annot.Bar\")";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(na);
-	}
-
-	public void testRemoveAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.NotBar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations=@annot.NotBar)";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceContains(na);
-	}
-
-	public void testRemoveAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.Bar(0), @annot.Bar(1), @annot.Bar(2), @annot.Bar(3)})";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertTrue(aa1.getAnnotation().isNormalAnnotation());
-		assertEquals(ASTNode.ARRAY_INITIALIZER, this.annotationElementValue(aa1.getAnnotation(), "nestedAnnotations").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains("@annot.Foo(nestedAnnotations={@annot.Bar(0), @annot.Bar(1), null, @annot.Bar(3)})");
-	}
-
-	public void testRemoveAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), @annot.Bar(1), @annot.Bar(2), @annot.Bar(3)})";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertTrue(aa1.getAnnotation().isSingleMemberAnnotation());
-		assertEquals(ASTNode.ARRAY_INITIALIZER, this.annotationElementValue(aa1.getAnnotation(), "value").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains("@annot.Foo({@annot.Bar(0), @annot.Bar(1), null, @annot.Bar(3)})");
-	}
-
-	public void testRemoveAnnotation10() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), @annot.Bar(1)})";
-		String expected = "@annot.Foo({null, @annot.Bar(1)})";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 0, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation11() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), @annot.Bar(1)})";
-		String expected = "@annot.Foo(@annot.Bar(0))";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 1, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.SINGLE_MEMBER_ANNOTATION, this.annotationElementValue(aa1.getAnnotation(), "value").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), null, @annot.Bar(2)})";
-		String expected = "@annot.Foo(@annot.Bar(0))";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.SINGLE_MEMBER_ANNOTATION, this.annotationElementValue(aa1.getAnnotation(), "value").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({null, @annot.Bar(1)})";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 1, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testRemoveAnnotation14() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), null, @annot.Bar(2), null})";
-		String expected = "@annot.Foo(@annot.Bar(0))";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.SINGLE_MEMBER_ANNOTATION, this.annotationElementValue(aa1.getAnnotation(), "value").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation15() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), null, @annot.Bar(2), @annot.Bar(3)})";
-		String expected = "@annot.Foo({@annot.Bar(0), null, null, @annot.Bar(3)})";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.ARRAY_INITIALIZER, this.annotationElementValue(aa1.getAnnotation(), "value").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation16() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String na = "@annot.Foo({@annot.Bar(0), null, @annot.Bar(2), @annot.Bar(3)})";
-		String expected = "@annot.Foo({@annot.Bar(0), null, @annot.Bar(2)})";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "value", 3, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.ARRAY_INITIALIZER, this.annotationElementValue(aa1.getAnnotation(), "value").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation17() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.Bar(0), null, @annot.Bar(2)})";
-		String expected = "@annot.Foo(nestedAnnotations=@annot.Bar(0))";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.SINGLE_MEMBER_ANNOTATION, this.annotationElementValue(aa1.getAnnotation(), "nestedAnnotations").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation18() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={null, @annot.Bar(1)})";
-		this.createTestType(na);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 1, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testRemoveAnnotation19() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.Bar(0), null, @annot.Bar(2), null})";
-		String expected = "@annot.Foo(nestedAnnotations=@annot.Bar(0))";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.SINGLE_MEMBER_ANNOTATION, this.annotationElementValue(aa1.getAnnotation(), "nestedAnnotations").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation20() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.Bar(0), null, @annot.Bar(2), @annot.Bar(3)})";
-		String expected = "@annot.Foo(nestedAnnotations={@annot.Bar(0), null, null, @annot.Bar(3)})";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 2, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.ARRAY_INITIALIZER, this.annotationElementValue(aa1.getAnnotation(), "nestedAnnotations").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testRemoveAnnotation21() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		String na = "@annot.Foo(nestedAnnotations={@annot.Bar(0), null, @annot.Bar(2), @annot.Bar(3)})";
-		String expected = "@annot.Foo(nestedAnnotations={@annot.Bar(0), null, @annot.Bar(2)})";
-		this.createTestType(na);
-		this.assertSourceDoesNotContain(expected);
-		this.assertSourceContains(na);
-
-		DeclarationAnnotationAdapter daa1 = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa1 = new MemberAnnotationAdapter(this.idField(), daa1);
-		DeclarationAnnotationAdapter daa2 = new NestedIndexedDeclarationAnnotationAdapter(daa1, "nestedAnnotations", 3, "annot.Bar");
-		AnnotationAdapter aa2 = new MemberAnnotationAdapter(this.idField(), daa2);
-		Annotation annotation = aa2.getAnnotation();
-		assertNotNull(annotation);
-
-		aa2.removeAnnotation();
-		assertEquals(ASTNode.ARRAY_INITIALIZER, this.annotationElementValue(aa1.getAnnotation(), "nestedAnnotations").getNodeType());
-		this.assertSourceDoesNotContain(na);
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@Foo(nestedAnnotations=@Bar)");
-	}
-
-	public void testNewMarkerAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("Foo");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@Foo(@Bar)");
-	}
-
-	public void testNewMarkerAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(nestedAnnotations=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String value(); annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@Foo(value=\"something\", nestedAnnotations=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@annot.Foo(@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", nestedAnnotations = @Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar[] value();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", value = @Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		assertNull(aa.getAnnotation());
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@Foo(nestedAnnotations={null,null,null,null,null,@Bar})");
-	}
-
-	public void testNewMarkerAnnotation10() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String value(); annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(\"something\")");
-		this.assertSourceDoesNotContain("Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@Foo(value=\"something\", nestedAnnotations={null,null,null,null,null,@Bar})");
-	}
-
-	public void testNewMarkerAnnotation11() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({\"one\", \"two\"})");
-		String expected = "@annot.Foo({@Bar, \"two\"})";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({\"one\", \"two\"})");
-		this.assertSourceDoesNotContain("Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("Bar})");  // split line
-	}
-
-	public void testNewMarkerAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(7)");
-		String expected = "@annot.Foo(@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation14() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(7)");
-		this.assertSourceDoesNotContain("Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@annot.Foo({7,null,null,null,null,@Bar})");
-	}
-
-	public void testNewMarkerAnnotation15() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(@annot.NotBar)");
-		String expected = "@annot.Foo(@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation16() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(@annot.Bar(55))");
-		String expected = "@annot.Foo({@annot.Bar(55),@Bar})";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 1, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation17() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={\"something\"})");
-		String expected = "@annot.Foo(nestedAnnotations={@Bar})";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation18() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={\"something\"})");
-		this.assertSourceDoesNotContain("Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("Bar})");  // split line
-	}
-
-	public void testNewMarkerAnnotation19() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=\"something\")");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation20() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation21() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("@annot.Foo(nestedAnnotations={@annot.NotBar,null,null,null,null,@Bar})");
-	}
-
-	public void testNewMarkerAnnotation22() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(88))");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar)";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation23() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(88))");
-		String expected = "@annot.Foo(nestedAnnotations={@annot.Bar(88),null,@Bar})";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 2, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation24() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(@annot.Bar(88))");
-		String expected = "@annot.Foo({@annot.Bar(88),null,@Bar})";
-		this.assertSourceDoesNotContain(expected);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 2, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected);
-	}
-
-	public void testNewMarkerAnnotation25() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={@annot.Bar(88), @annot.Bar(77)})");
-		String expected1 = "@annot.Foo(nestedAnnotations={@annot.Bar(88), @annot.Bar(77), null, null,";  // the line gets split
-		String expected2 = "@Bar})";
-		this.assertSourceDoesNotContain(expected1);
-		this.assertSourceDoesNotContain(expected2);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 4, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected1);
-		this.assertSourceContains(expected2);
-	}
-
-	public void testNewMarkerAnnotation26() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(88), @annot.Bar(77)})");
-		String expected1 = "@annot.Foo({@annot.Bar(88), @annot.Bar(77), null, null,";  // the line gets split
-		String expected2 = "@Bar})";
-		this.assertSourceDoesNotContain(expected1);
-		this.assertSourceDoesNotContain(expected2);
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 4, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		aa.newMarkerAnnotation();
-		this.assertSourceContains(expected1);
-		this.assertSourceContains(expected2);
-	}
-
-	public void testNewSingleMemberAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation1(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(nestedAnnotations=@Bar(88))");
-	}
-
-	void editNewSingleMemberAnnotation1(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation2(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(@Bar(88))");
-	}
-
-	void editNewSingleMemberAnnotation2(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(nestedAnnotations=@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation3(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation3(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation4(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation4(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String value(); annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@Foo(value=\"something\", nestedAnnotations=@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation5(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation5(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@annot.Foo(@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation6(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation6(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", nestedAnnotations = @Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation7(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation7(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String xxx(); annot.Bar[] value();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", value = @Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation8(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation8(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newSingleMemberAnnotation();
-		this.assertSourceContains("@Foo(nestedAnnotations={null,null,null,null,null,@Bar(MISSING)})");  // ???
-	}
-
-	public void testNewSingleMemberAnnotation10() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "String value(); annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(\"something\")");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newSingleMemberAnnotation();
-		this.assertSourceContains("@Foo(value=\"something\", nestedAnnotations={null,null,null,null,null,@Bar(MISSING)})");  // ???
-	}
-
-	public void testNewSingleMemberAnnotation11() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({\"one\", \"two\"})");
-		String expected = "@annot.Foo({@Bar(88), \"two\"})";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation11(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation11(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({\"one\", \"two\"})");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newSingleMemberAnnotation();
-		this.assertSourceContains("@Bar(MISSING)})");  // split line
-	}
-
-	public void testNewSingleMemberAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(7)");
-		String expected = "@annot.Foo(@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation13(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation13(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation14() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(7)");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newSingleMemberAnnotation();
-		this.assertSourceContains("@annot.Foo({7,null,null,null,null,@Bar(MISSING)})");
-	}
-
-	public void testNewSingleMemberAnnotation15() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(@annot.NotBar)");
-		String expected = "@annot.Foo(@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation15(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation15(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation16() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(@annot.Bar(55))");
-		String expected = "@annot.Foo({@annot.Bar(55),@Bar(88)})";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation16(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation16(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 1, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation17() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={\"something\"})");
-		String expected = "@annot.Foo(nestedAnnotations={@Bar(88)})";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation17(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation17(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation18() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={\"something\"})");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newSingleMemberAnnotation();
-		this.assertSourceContains("@Bar(MISSING)})");  // ???
-	}
-
-	public void testNewSingleMemberAnnotation19() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=\"something\")");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation19(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation19(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation20() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation20(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation20(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewSingleMemberAnnotation21() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int value();");
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newSingleMemberAnnotation();
-		this.assertSourceContains("@annot.Foo(nestedAnnotations={@annot.NotBar,null,null,null,null,@Bar(MISSING)})");
-	}
-
-	public void testNewSingleMemberAnnotation22() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(77))");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar(88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation22(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewSingleMemberAnnotation22(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		SingleMemberAnnotation annotation = daa.newSingleMemberAnnotation(declaration);
-		NumberLiteral numberLiteral = annotation.getAST().newNumberLiteral();
-		numberLiteral.setToken("88");
-		annotation.setValue(numberLiteral);
-	}
-
-	public void testNewNormalAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation1(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(nestedAnnotations=@Bar(xxx=88))");
-	}
-
-	void editNewNormalAnnotation1(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation2(declaration);
-			}
-		});
-		this.assertSourceContains("@Foo(@Bar(xxx=88))");
-	}
-
-	void editNewNormalAnnotation2(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(nestedAnnotations=@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation3(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation3(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations();");
-		this.createTestType("@annot.Foo");
-		String expected = "@Foo(@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation4(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation4(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations(); String value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@Foo(value=\"something\", nestedAnnotations=@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation5(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation5(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		String expected = "@annot.Foo(@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation6(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation6(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations(); String xxx();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", nestedAnnotations = @Bar(xxx = 88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation7(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation7(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value(); String xxx();");
-		this.createTestType("@annot.Foo(xxx=\"something\")");
-		String expected = "@annot.Foo(xxx=\"something\", value = @Bar(xxx = 88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation8(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation8(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations(); String xxx();");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newNormalAnnotation();
-		this.assertSourceContains("@Foo(nestedAnnotations={null,null,null,null,null,@Bar()})");
-	}
-
-	public void testNewNormalAnnotation10() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] nestedAnnotations(); String value();");
-		this.createTestType("@annot.Foo(\"something\")");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newNormalAnnotation();
-		this.assertSourceContains("@Foo(value=\"something\", nestedAnnotations={null,null,null,null,null,@Bar()})");
-	}
-
-	public void testNewNormalAnnotation11() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({\"one\", \"two\"})");
-		String expected = "@annot.Foo({@Bar(xxx=88), \"two\"})";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation11(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation11(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo({\"one\", \"two\"})");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newNormalAnnotation();
-		this.assertSourceContains("@Bar()})");  // split line
-	}
-
-	public void testNewNormalAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(7)");
-		String expected = "@annot.Foo(@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation13(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation13(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation14() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(7)");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newNormalAnnotation();
-		this.assertSourceContains("@annot.Foo({7,null,null,null,null,@Bar()})");
-	}
-
-	public void testNewNormalAnnotation15() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int xxx();");
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] value();");
-		this.createTestType("@annot.Foo(@annot.NotBar)");
-		String expected = "@annot.Foo(@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation15(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation15(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation16() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(@annot.Bar(55))");
-		String expected = "@annot.Foo({@annot.Bar(55),@Bar(xxx=88)})";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation16(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation16(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 1, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation17() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={\"something\"})");
-		String expected = "@annot.Foo(nestedAnnotations={@Bar(xxx=88)})";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation17(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation17(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation18() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations={\"something\"})");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newNormalAnnotation();
-		this.assertSourceContains("@Bar()})");  // split line
-	}
-
-	public void testNewNormalAnnotation19() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=\"something\")");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation19(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation19(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation20() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int xxx();");
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation20(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation20(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testNewNormalAnnotation21() throws Exception {
-		this.createAnnotationAndMembers("NotBar", "int xxx();");
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.NotBar)");
-		this.assertSourceDoesNotContain("@Bar");
-
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 5, "annot.Bar");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newNormalAnnotation();
-		this.assertSourceContains("@annot.Foo(nestedAnnotations={@annot.NotBar,null,null,null,null,@Bar()})");
-	}
-
-	public void testNewNormalAnnotation22() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int xxx();");
-		this.createAnnotationAndMembers("Foo", "Object[] nestedAnnotations();");
-		this.createTestType("@annot.Foo(nestedAnnotations=@annot.Bar(77))");
-		String expected = "@annot.Foo(nestedAnnotations=@Bar(xxx=88))";
-		this.assertSourceDoesNotContain(expected);
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				NestedIndexedDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation22(declaration);
-			}
-		});
-		this.assertSourceContains(expected);
-	}
-
-	void editNewNormalAnnotation22(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "nestedAnnotations", 0, "annot.Bar");
-		NormalAnnotation annotation = daa.newNormalAnnotation(declaration);
-		this.addMemberValuePair(annotation, "xxx", 88);
-	}
-
-	public void testMoveAnnotation1() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(@annot.Bar(00))");
-		String expected = "@annot.Foo({null,@annot.Bar(00)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(1);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation2() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({null, @annot.Bar(11)})");
-		String expected = "@annot.Foo(@annot.Bar(11))";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 1, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation3() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), @annot.Bar(22), @annot.Bar(33)})");
-		String expected = "@annot.Foo({@annot.Bar(33), @annot.Bar(11), @annot.Bar(22)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 3, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation4() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), @annot.Bar(22), @annot.Bar(33), @annot.Bar(44)})");
-		String expected = "@annot.Foo({@annot.Bar(33), @annot.Bar(11), @annot.Bar(22), null, @annot.Bar(44)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 3, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation5() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), @annot.Bar(22)})");
-		String expected = "@annot.Foo({@annot.Bar(00), @annot.Bar(11), null, @annot.Bar(22)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 2, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(3);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation6() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), @annot.Bar(22)})");
-		String expected = "@annot.Foo({null, @annot.Bar(11), @annot.Bar(22), @annot.Bar(00)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(3);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation7() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), @annot.Bar(22)})");
-		String expected = "@annot.Foo({null, @annot.Bar(11), @annot.Bar(22)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 3, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation8() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), @annot.Bar(22), null, @annot.Bar(44)})");
-		String expected = "@annot.Foo({null, @annot.Bar(11), @annot.Bar(22), null, @annot.Bar(44)})";
-		this.assertSourceDoesNotContain(expected);
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 3, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation9() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		String expected = "@annot.Foo({null, @annot.Bar(11), @annot.Bar(22)})";
-		this.createTestType(expected);  // the source should be unchanged
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 0, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(3);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation10() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11)})");
-		String expected = "@annot.Foo(@annot.Bar(00))";
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 2, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-		iaa.moveAnnotation(1);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation11() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo(@annot.Bar(00))");
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 1, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceDoesNotContain("Foo");
-	}
-
-	public void testMoveAnnotation12() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), null, @annot.Bar(22)})");
-		String expected = "@annot.Foo(@annot.Bar(22))";
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 2, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-	public void testMoveAnnotation13() throws Exception {
-		this.createAnnotationAndMembers("Bar", "int value();");
-		this.createAnnotationAndMembers("Foo", "annot.Bar[] value();");
-		this.createTestType("@annot.Foo({@annot.Bar(00), @annot.Bar(11), null, @annot.Bar(33)})");
-		String expected = "@annot.Foo({@annot.Bar(33), @annot.Bar(11)})";
-
-		IndexedDeclarationAnnotationAdapter idaa = new NestedIndexedDeclarationAnnotationAdapter(
-				new SimpleDeclarationAnnotationAdapter("annot.Foo"), "value", 3, "annot.Bar");
-		IndexedAnnotationAdapter iaa = new MemberIndexedAnnotationAdapter(this.idField(), idaa);
-		Annotation annotation = iaa.getAnnotation();
-		assertNotNull(annotation);
-
-		iaa.moveAnnotation(0);
-		this.assertSourceContains(expected);
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/SimpleDeclarationAnnotationAdapterTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/SimpleDeclarationAnnotationAdapterTests.java
deleted file mode 100644
index 0e014b6..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/SimpleDeclarationAnnotationAdapterTests.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Annotation;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.MemberValuePair;
-import org.eclipse.jdt.core.dom.NormalAnnotation;
-import org.eclipse.jdt.core.dom.NumberLiteral;
-import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
-import org.eclipse.jdt.core.dom.StringLiteral;
-import org.eclipse.jpt.core.internal.jdtutility.AnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.DeclarationAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.Member;
-import org.eclipse.jpt.core.internal.jdtutility.MemberAnnotationAdapter;
-import org.eclipse.jpt.core.internal.jdtutility.ModifiedDeclaration;
-import org.eclipse.jpt.core.internal.jdtutility.SimpleDeclarationAnnotationAdapter;
-
-public class SimpleDeclarationAnnotationAdapterTests extends AnnotationTestCase {
-
-	public SimpleDeclarationAnnotationAdapterTests(String name) {
-		super(name);
-	}
-
-	private void createAnnotation(String annotationName) throws Exception {
-		this.javaProject.createType("annot", annotationName + ".java", "public @interface " + annotationName + " {}");
-	}
-
-	public void testGetAnnotation1() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("@annot.Foo");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Foo", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-	}
-
-	public void testGetAnnotation2() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("@annot.Foo(1) @annot.Foo(2)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("annot.Foo", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isSingleMemberAnnotation());
-		Expression value = ((SingleMemberAnnotation) annotation).getValue();
-		assertEquals(ASTNode.NUMBER_LITERAL, value.getNodeType());
-		assertEquals("1", ((NumberLiteral) value).getToken());
-	}
-
-	public void testGetAnnotation3() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("annot.Foo", "@Foo");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-		assertEquals("Foo", annotation.getTypeName().getFullyQualifiedName());
-		assertTrue(annotation.isMarkerAnnotation());
-	}
-
-	public void testGetAnnotationNull1() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType();
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-	}
-
-	public void testGetAnnotationNull2() throws Exception {
-		this.createAnnotation("Foo");
-		this.createAnnotation("Fop");
-		this.createTestType("@annot.Fop");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-		this.assertSourceContains("@annot.Fop");
-	}
-
-	public void testGetAnnotationNull3() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("@annot.Foo");
-		// un-qualified name
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-		this.assertSourceContains("@annot.Foo");
-	}
-
-	public void testRemoveAnnotation1() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("@annot.Foo");
-		this.assertSourceContains("@annot.Foo");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("@annot.Foo");
-	}
-
-	public void testRemoveAnnotation2() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("@annot.Foo(1) @annot.Foo(2)");
-		this.assertSourceContains("@annot.Foo(1) @annot.Foo(2)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.removeAnnotation();
-		this.assertSourceDoesNotContain("@annot.Foo(1)");
-		this.assertSourceContains("@annot.Foo(2)");
-	}
-
-	public void testNewMarkerAnnotation1() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@annot.Foo");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("import annot.Foo;");
-		this.assertSourceContains("@Foo");
-	}
-
-	public void testNewMarkerAnnotation2() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType("@annot.Foo(88)");
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		AnnotationAdapter aa = new MemberAnnotationAdapter(this.idField(), daa);
-		Annotation annotation = aa.getAnnotation();
-		assertNotNull(annotation);
-
-		aa.newMarkerAnnotation();
-		this.assertSourceContains("import annot.Foo;");
-		this.assertSourceContains("@Foo");
-		this.assertSourceDoesNotContain("@annot.Foo(88)");
-	}
-
-	public void testNewSingleMemberAnnotation() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				SimpleDeclarationAnnotationAdapterTests.this.editNewSingleMemberAnnotation(declaration);
-			}
-		});
-		this.assertSourceContains("import annot.Foo;");
-		this.assertSourceContains("@Foo(\"test string literal\")");
-	}
-
-	void editNewSingleMemberAnnotation(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		SingleMemberAnnotation annotation = (SingleMemberAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newSingleMemberAnnotation(declaration);
-		StringLiteral stringLiteral = annotation.getAST().newStringLiteral();
-		stringLiteral.setLiteralValue("test string literal");
-		annotation.setValue(stringLiteral);
-	}
-
-	public void testNewNormalAnnotation() throws Exception {
-		this.createAnnotation("Foo");
-		this.createTestType();
-		this.assertSourceDoesNotContain("@Foo");
-		this.idField().edit(new Member.Editor() {
-			public void edit(ModifiedDeclaration declaration) {
-				SimpleDeclarationAnnotationAdapterTests.this.editNewNormalAnnotation(declaration);
-			}
-		});
-		this.assertSourceContains("import annot.Foo;");
-		this.assertSourceContains("@Foo(bar=\"test string literal\")");
-	}
-
-	void editNewNormalAnnotation(ModifiedDeclaration declaration) {
-		DeclarationAnnotationAdapter daa = new SimpleDeclarationAnnotationAdapter("annot.Foo");
-		NormalAnnotation annotation = (NormalAnnotation) daa.getAnnotation(declaration);
-		assertNull(annotation);
-		annotation = daa.newNormalAnnotation(declaration);
-		MemberValuePair mvp = this.newMemberValuePair(annotation.getAST(), "bar", "test string literal");
-		this.values(annotation).add(mvp);
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/TypeTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/TypeTests.java
deleted file mode 100644
index 6371156..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/jdtutility/TypeTests.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.jdtutility;
-
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jpt.core.internal.ITextRange;
-import org.eclipse.jpt.core.internal.jdtutility.Type;
-
-public class TypeTests extends AnnotationTestCase {
-
-	private IType jdtType;
-	private Type testType;
-
-
-	public TypeTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		this.jdtType = this.createTestType();
-		this.testType = new Type(this.jdtType);
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		this.testType = null;
-		this.jdtType = null;
-		super.tearDown();
-	}
-
-	public void testGetJdtMember() throws Exception {
-		assertEquals(this.jdtType, this.testType.getJdtMember());
-	}
-
-	public void testIsAbstract() throws Exception {
-		assertFalse(this.testType.isAbstract());
-	}
-
-	public void testTopLevelDeclaringType() throws Exception {
-		assertEquals(this.testType, this.testType.topLevelDeclaringType());
-	}
-
-	public void testGetDeclaringType() throws Exception {
-		assertNull(this.testType.getDeclaringType());
-	}
-
-	public void testGetName() throws Exception {
-		assertEquals(TYPE_NAME, this.testType.getName());
-	}
-
-	public void testTextRange() throws Exception {
-		String source = this.jdtType.getOpenable().getBuffer().getContents();
-		ITextRange textRange = this.testType.textRange();
-		String body = source.substring(textRange.getOffset());
-		assertTrue(body.startsWith("public class " + TYPE_NAME));
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/model/JptCoreModelTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/model/JptCoreModelTests.java
deleted file mode 100644
index d7d2ffe..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/model/JptCoreModelTests.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2007 Oracle. All rights reserved. This
- *  program and the accompanying materials are made available under the terms of
- *  the Eclipse Public License v1.0 which accompanies this distribution, and is
- *  available at http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: Oracle. - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.model;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class JptCoreModelTests {
-
-	public static Test suite() {
-		TestSuite suite = new TestSuite(JptCoreModelTests.class.getPackage().getName());
-		suite.addTestSuite(ModelInitializationTests.class);
-		return suite;
-	}
-
-	private JptCoreModelTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/model/ModelInitializationTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/model/ModelInitializationTests.java
deleted file mode 100644
index 620ec25..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/model/ModelInitializationTests.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.model;
-
-import junit.framework.TestCase;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jpt.core.internal.IJpaModel;
-import org.eclipse.jpt.core.internal.IJpaProject;
-import org.eclipse.jpt.core.internal.JptCorePlugin;
-import org.eclipse.jpt.core.tests.internal.ProjectUtility;
-import org.eclipse.jpt.core.tests.internal.projects.TestFacetedProject;
-import org.eclipse.jpt.utility.internal.ClassTools;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-
-public class ModelInitializationTests extends TestCase {
-	private IJpaModel jpaModel;
-	
-	
-	public ModelInitializationTests(String name) {
-		super(name);
-	}
-	
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		ProjectUtility.deleteAllProjects();
-		this.jpaModel = JptCorePlugin.getJpaModel();
-	}
-	
-	@Override
-	protected void tearDown() throws Exception {
-		ProjectUtility.deleteAllProjects();
-		this.jpaModel = null;
-		super.tearDown();
-	}
-
-	/** 
-	 * Builds a project with the java and utility facets installed, and with
-	 * pre-existing entities added.
-	 */
-	private TestFacetedProject buildTestProject() throws CoreException {
-		TestFacetedProject testProject = new TestFacetedProject(ClassTools.shortClassNameForObject(this), true);
-		testProject.installFacet("jst.java", "5.0");
-		testProject.installFacet("jst.utility", "1.0");
-		testProject.createFile(
-			new Path("src/test.pkg/TestEntity.java"),
-			"package test.pkg; @Entity public class TestEntity {}");
-		testProject.createFile(
-			new Path("src/test.pkg/TestEntity2.java"),
-			"package test.pkg; @Entity public class TestEntity2 {}");
-		return testProject;
-	}	
-		
-	public void testBasic() {
-		assertNotNull(this.jpaModel);
-	}
-	
-	public void testFacetInstallation() throws CoreException {
-		TestFacetedProject testProject = buildTestProject();
-		assertNull(this.jpaModel.getJpaProject(testProject.getProject()));
-		testProject.installFacet("jpt.jpa", "1.0");
-		assertEquals(1, CollectionTools.size(this.jpaModel.jpaProjects()));
-		IJpaProject jpaProject = this.jpaModel.getJpaProject(testProject.getProject());
-		assertNotNull(jpaProject);
-		assertEquals(4, CollectionTools.size(jpaProject.jpaFiles()));
-		assertNotNull(jpaProject.getJpaFile(testProject.getProject().getFile(new Path("src/test.pkg/TestEntity.java"))));
-		assertNotNull(jpaProject.getJpaFile(testProject.getProject().getFile(new Path("src/test.pkg/TestEntity2.java"))));
-	}
-	
-	public void testProjectOpening() throws CoreException {
-		TestFacetedProject testProject = buildTestProject();
-		testProject.installFacet("jpt.jpa", "1.0");
-		testProject.close();
-		assertTrue(! testProject.getProject().isOpen());
-		testProject.open();
-		IJpaProject jpaProject = this.jpaModel.getJpaProject(testProject.getProject());
-		assertNotNull(jpaProject);
-		assertNotNull(jpaProject.getJpaFile(testProject.getProject().getFile(new Path("src/test.pkg/TestEntity.java"))));
-		assertNotNull(jpaProject.getJpaFile(testProject.getProject().getFile(new Path("src/test.pkg/TestEntity2.java"))));
-	}
-	
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/platform/BaseJpaPlatformTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/platform/BaseJpaPlatformTests.java
deleted file mode 100644
index 94c306e..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/platform/BaseJpaPlatformTests.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.eclipse.jpt.core.tests.internal.platform;
-
-import java.io.IOException;
-import junit.framework.TestCase;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jpt.core.internal.IJpaFile;
-import org.eclipse.jpt.core.internal.content.orm.EntityMappingsInternal;
-import org.eclipse.jpt.core.internal.content.orm.OrmFactory;
-import org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal;
-import org.eclipse.jpt.core.internal.content.orm.XmlRootContentNode;
-import org.eclipse.jpt.core.internal.content.persistence.JavaClassRef;
-import org.eclipse.jpt.core.internal.content.persistence.Persistence;
-import org.eclipse.jpt.core.internal.content.persistence.PersistenceFactory;
-import org.eclipse.jpt.core.internal.content.persistence.PersistenceXmlRootContentNode;
-import org.eclipse.jpt.core.tests.internal.projects.TestJpaProject;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-
-public class BaseJpaPlatformTests extends TestCase
-{
-	protected TestJpaProject jpaProject;
-
-	protected static final String PROJECT_NAME = "PlatformTestProject";
-	protected static final String PACKAGE_NAME = "platform.test";
-	protected static final String PERSISTENCE_XML_LOCATION = "src/META-INF/persistence.xml";
-	protected static final String ORM_XML_LOCATION = "src/META-INF/orm.xml";
-	
-	
-	public BaseJpaPlatformTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-		jpaProject = this.buildJpaProject(PROJECT_NAME, false);  // false = no auto-build
-	}
-
-	protected TestJpaProject buildJpaProject(String projectName, boolean autoBuild) throws Exception {
-		return new TestJpaProject(projectName, autoBuild);  // false = no auto-build
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		jpaProject.dispose();
-		jpaProject = null;
-		super.tearDown();
-	}
-	
-	
-	public void testPersistentTypes() throws CoreException, IOException {
-		IFile persistenceXmlIFile = jpaProject.getProject().getFile(PERSISTENCE_XML_LOCATION);
-		IJpaFile persistenceXmlJpaFile = jpaProject.getJpaProject().getJpaFile(persistenceXmlIFile);
-		PersistenceXmlRootContentNode persistenceRoot = (PersistenceXmlRootContentNode) persistenceXmlJpaFile.getContent();
-		Persistence persistence = persistenceRoot.getPersistence();
-		
-		IFile ormXmlIFile = jpaProject.getProject().getFile(ORM_XML_LOCATION);
-		IJpaFile ormXmlJpaFile = jpaProject.getJpaProject().getJpaFile(ormXmlIFile);
-		XmlRootContentNode ormRoot = (XmlRootContentNode) ormXmlJpaFile.getContent();
-		EntityMappingsInternal entityMappings = ormRoot.getEntityMappings();
-		
-		// add xml persistent type
-		XmlEntityInternal xmlEntity = OrmFactory.eINSTANCE.createXmlEntityInternal();
-		xmlEntity.setSpecifiedName("XmlEntity");
-		entityMappings.getTypeMappings().add(xmlEntity);
-		entityMappings.eResource().save(null);
-		
-		assertEquals(1, CollectionTools.size(jpaProject.getJpaProject().getPlatform().persistentTypes(PROJECT_NAME)));
-		
-		// add java persistent type
-		jpaProject.createType(PACKAGE_NAME, "JavaEntity.java", 
-				"@Entity public class JavaEntity {}"
-			);
-		JavaClassRef javaClassRef = PersistenceFactory.eINSTANCE.createJavaClassRef();
-		javaClassRef.setJavaClass(PACKAGE_NAME + ".JavaEntity");
-		persistence.getPersistenceUnits().get(0).getClasses().add(javaClassRef);
-		persistence.eResource().save(null);
-		
-		assertEquals(2, CollectionTools.size(jpaProject.getJpaProject().getPlatform().persistentTypes(PROJECT_NAME)));
-	}
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/platform/JptCorePlatformTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/platform/JptCorePlatformTests.java
deleted file mode 100644
index 589e631..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/platform/JptCorePlatformTests.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- *  Copyright (c) 2007 Oracle. 
- *  All rights reserved.  This program and the accompanying materials 
- *  are made available under the terms of the Eclipse Public License v1.0 
- *  which accompanies this distribution, and is available at 
- *  http://www.eclipse.org/legal/epl-v10.html
- *  
- *  Contributors: 
- *  	Oracle - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.platform;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class JptCorePlatformTests
-{
-	public static Test suite() {
-		TestSuite suite = new TestSuite(JptCorePlatformTests.class.getName());
-//		suite.addTestSuite(BaseJpaPlatformTests.class);
-		return suite;
-	}
-
-	private JptCorePlatformTests() {
-		super();
-		throw new UnsupportedOperationException();
-	}
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestFacetedProject.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestFacetedProject.java
deleted file mode 100644
index 6b638fa..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestFacetedProject.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.projects;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.wst.common.project.facet.core.IFacetedProject;
-import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
-import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
-
-public class TestFacetedProject extends TestPlatformProject {
-	private IFacetedProject facetedProject;
-
-
-	// ********** constructors/initialization **********
-
-	public TestFacetedProject(String projectName) throws CoreException {
-		this(projectName, true);
-	}
-
-	public TestFacetedProject(String projectName, boolean autoBuild) throws CoreException {
-		super(projectName, autoBuild);
-		this.facetedProject = this.createFacetedProject();
-	}
-
-	private IFacetedProject createFacetedProject() throws CoreException {
-		return ProjectFacetsManager.create(this.getProject(), true, null);		// true = "convert if necessary"
-	}
-
-
-	// ********** public methods **********
-
-	public IFacetedProject getFacetedProject() {
-		return this.facetedProject;
-	}
-
-	public void installFacet(String facetName, String versionName) throws CoreException {
-		IProjectFacetVersion facetVersion = ProjectFacetsManager.getProjectFacet(facetName).getVersion(versionName);
-		this.facetedProject.installProjectFacet(facetVersion, null, null);
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestJavaProject.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestJavaProject.java
deleted file mode 100644
index a19529b..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestJavaProject.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.projects;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.search.IJavaSearchConstants;
-import org.eclipse.jdt.core.search.SearchEngine;
-import org.eclipse.jdt.core.search.SearchPattern;
-import org.eclipse.jdt.core.search.TypeNameRequestor;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-
-/**
- * This builds and holds a "Java" project.
- * Support for adding packages and types.
- */
-public class TestJavaProject extends TestFacetedProject {
-
-	private IJavaProject javaProject;
-	private IPackageFragmentRoot sourceFolder;
-
-
-	// ********** constructors/initialization **********
-
-	public TestJavaProject() throws CoreException {
-		this("TestJavaProject");
-	}
-
-	public TestJavaProject(String projectName) throws CoreException {
-		this(projectName, false);
-	}
-
-	public TestJavaProject(String projectName, boolean autoBuild) throws CoreException {
-		super(projectName, autoBuild);
-		this.installFacet("jst.java", "5.0");
-		this.javaProject = JavaCore.create(this.getProject());
-		this.sourceFolder = this.javaProject.getPackageFragmentRoot(this.getProject().getFolder("src"));
-	}
-
-	protected void addJar(String jarPath) throws JavaModelException {
-		this.addClasspathEntry(JavaCore.newLibraryEntry(new Path(jarPath), null, null));
-	}
-
-	private void addClasspathEntry(IClasspathEntry entry) throws JavaModelException {
-		this.javaProject.setRawClasspath(CollectionTools.add(this.javaProject.getRawClasspath(), entry), null);
-	}
-	
-
-	// ********** public methods **********
-
-	public IPackageFragment createPackage(String packageName) throws CoreException {
-		return this.sourceFolder.createPackageFragment(packageName, false, null);	// false = "no force"
-	}
-
-	/**
-	 * The source should NOT contain a package declaration;
-	 * it will be added here.
-	 */
-	public IType createType(String packageName, String compilationUnitName, String source) throws CoreException {
-		return this.createType(this.createPackage(packageName), compilationUnitName, new SimpleSourceWriter(source));
-	}
-
-	/**
-	 * The source should NOT contain a package declaration;
-	 * it will be added here.
-	 */
-	public IType createType(String packageName, String compilationUnitName, SourceWriter sourceWriter) throws CoreException {
-		return this.createType(this.createPackage(packageName), compilationUnitName, sourceWriter);
-	}
-
-	/**
-	 * The source should NOT contain a package declaration;
-	 * it will be added here.
-	 */
-	public IType createType(IPackageFragment packageFragment, String compilationUnitName, SourceWriter sourceWriter) throws CoreException {
-		StringBuffer sb = new StringBuffer(2000);
-		sb.append("package ").append(packageFragment.getElementName()).append(";").append(CR);
-		sb.append(CR);
-		sourceWriter.appendSourceTo(sb);
-		String source = sb.toString();
-		ICompilationUnit cu = packageFragment.createCompilationUnit(compilationUnitName, source, false, null);	// false = "no force"
-		return cu.findPrimaryType();
-	}
-
-	public IType findType(String fullyQualifiedName) throws JavaModelException {
-		return this.javaProject.findType(fullyQualifiedName);
-	}
-
-	@Override
-	public void dispose() throws CoreException {
-		this.waitForIndexer();
-		this.sourceFolder = null;
-		this.javaProject = null;
-		super.dispose();
-	}
-
-
-	// ********** internal methods **********
-
-	private void waitForIndexer() throws JavaModelException {
-		new SearchEngine().searchAllTypeNames(
-			null,
-			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
-			null,
-			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
-			IJavaSearchConstants.CLASS,
-			SearchEngine.createJavaSearchScope(new IJavaElement[0]),
-			new TypeNameRequestor() {/* do nothing */},
-			IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
-			null
-		);
-	}
-
-
-	// ********** member classes **********
-
-	public interface SourceWriter {
-		void appendSourceTo(StringBuffer sb);
-	}
-
-	public class SimpleSourceWriter implements SourceWriter {
-		private final String source;
-		public SimpleSourceWriter(String source) {
-			super();
-			this.source = source;
-		}
-		public void appendSourceTo(StringBuffer sb) {
-			sb.append(source);
-		}
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestJpaProject.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestJpaProject.java
deleted file mode 100644
index 68f01e8..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestJpaProject.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.projects;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jpt.core.internal.IJpaProject;
-import org.eclipse.jpt.core.internal.JptCorePlugin;
-
-public class TestJpaProject extends TestJavaProject {
-	private IJpaProject jpaProject;
-
-	public static final String JAR_NAME_SYSTEM_PROPERTY = "org.eclipse.jpt.jpa.jar";
-
-	// ********** constructors/initialization **********
-
-	public TestJpaProject() throws CoreException {
-		this("TestJpaProject");
-	}
-
-	public TestJpaProject(String projectName) throws CoreException {
-		this(projectName, false);
-	}
-	
-	public TestJpaProject(String projectName, boolean autoBuild) throws CoreException {
-		super(projectName, autoBuild);
-		this.installFacet("jst.utility", "1.0");
-		this.installFacet("jpt.jpa", "1.0");
-		this.addJar(this.jarName());
-		this.jpaProject = JptCorePlugin.getJpaProject(this.getProject());
-	}
-
-	protected String jarName() {
-		String jarName = System.getProperty(JAR_NAME_SYSTEM_PROPERTY);
-		if (jarName == null) {
-			throw new RuntimeException("missing Java system property: \"" + JAR_NAME_SYSTEM_PROPERTY + "\"");
-		}
-		return jarName;
-	}
-
-
-	// ********** public methods **********
-
-	public IJpaProject getJpaProject() {
-		return this.jpaProject;
-	}
-
-	@Override
-	public void dispose() throws CoreException {
-		this.jpaProject = null;
-		super.dispose();
-	}
-
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestPlatformProject.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestPlatformProject.java
deleted file mode 100644
index 7fbca79..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/projects/TestPlatformProject.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.projects;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IWorkspaceDescription;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-
-/**
- * This builds and holds a "general" project.
- * Support for adding natures, folders, and files.
- */
-public class TestPlatformProject {
-
-	private final IProject project;
-
-	/** carriage return */
-	public static final String CR = System.getProperty("line.separator");
-
-
-	// ********** constructors/initialization **********
-
-	public TestPlatformProject() throws CoreException {
-		this(false);
-	}
-
-	public TestPlatformProject(boolean autoBuild) throws CoreException {
-		this("TestProject", autoBuild);
-	}
-
-	public TestPlatformProject(String projectName, boolean autoBuild) throws CoreException {
-		super();
-		this.setAutoBuild(autoBuild);  // workspace-wide setting
-		this.project = this.createPlatformProject(projectName);
-	}
-
-	private void setAutoBuild(boolean autoBuild) throws CoreException {
-		IWorkspaceDescription description = ResourcesPlugin.getWorkspace().getDescription();
-		description.setAutoBuilding(autoBuild);
-		ResourcesPlugin.getWorkspace().setDescription(description);
-	}
-
-	private IProject createPlatformProject(String projectName) throws CoreException {
-		IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
-		p.create(null);
-		p.open(null);
-		return p;
-	}
-
-
-	// ********** public methods **********
-
-	public IProject getProject() {
-		return this.project;
-	}
-
-	public void addProjectNature(String natureID) throws CoreException {
-		IProjectDescription description = this.project.getDescription();
-		description.setNatureIds((String[]) CollectionTools.add(description.getNatureIds(), natureID));
-		this.project.setDescription(description, null);
-	}
-
-	public void removeProjectNature(String natureID) throws CoreException {
-		IProjectDescription description = this.project.getDescription();
-		description.setNatureIds((String[]) CollectionTools.removeAllOccurrences(description.getNatureIds(), natureID));
-		this.project.setDescription(description, null);
-	}
-
-	/**
-	 * Create a folder with the specified name directly under the project.
-	 */
-	public IFolder createFolder(String folderName) throws CoreException {
-		return this.createFolder(this.project, new Path(folderName));
-	}
-
-	/**
-	 * Create a folder in the specified container with the specified name.
-	 */
-	public IFolder createFolder(IContainer container, String folderName) throws CoreException {
-		return this.createFolder(container, new Path(folderName));
-	}
-	
-	/**
-	 * Create a folder in the specified container with the specified path.
-	 */
-	public IFolder createFolder(IContainer container, IPath folderPath) throws CoreException {
-		IFolder folder = container.getFolder(folderPath);
-		if ( ! folder.exists()) {
-			folder.create(false, true, null);		// false = "no force"; true = "local"
-		}
-		return folder;
-	}
-	
-	/**
-	 * Create a file with the specified name and content directly under the project.
-	 */
-	public IFile createFile(String fileName, String content) throws CoreException {
-		return this.createFile(this.project, fileName, content);
-	}
-	
-	/**
-	 * Create a file in the specified container with the specified name and content.
-	 */
-	public IFile createFile(IContainer container, String fileName, String content) throws CoreException {
-		return createFile(container, new Path(fileName), content);
-	}
-	
-	/**
-	 * Create a file in the project with the specified [relative] path
-	 * and content.
-	 */
-	public IFile createFile(IPath filePath, String content) throws CoreException {
-		return this.createFile(this.project, filePath, content);
-	}
-	
-	/**
-	 * Create a file in the specified container with the specified path and content.
-	 */
-	public IFile createFile(IContainer container, IPath filePath, String content) throws CoreException {
-		return this.createFile(container, filePath, new ByteArrayInputStream(content.getBytes()));
-	}
-	
-	/**
-	 * Create a file in the specified container with the specified path and contents.
-	 */
-	public IFile createFile(IContainer container, IPath filePath, InputStream content) throws CoreException {
-		int len = filePath.segmentCount() - 1;
-		for (int i = 0; i < len; i++) {
-			container = container.getFolder(new Path(filePath.segment(i)));
-			if ( ! container.exists()) {
-				((IFolder) container).create(true, true, null);		// true = "force"; true = "local"
-			}
-		}
-
-		IFile file = container.getFile(new Path(filePath.lastSegment()));
-		if (file.exists()) {
-			file.delete(true, null);		// true = "force"
-		}
-		file.create(content, true, null);		// true = "force"
-		return file;
-	}
-
-	public void open() throws CoreException {
-		this.project.open(null);
-		waitForJobs();
-	}
-
-	public void close() throws CoreException {
-		this.project.close(null);
-		waitForJobs();
-	}
-
-	public void dispose() throws CoreException {
-		this.project.delete(true, true, null);		// true = "delete content"; true = "force"
-		for (int i = 1; this.project.exists(); i++) {
-			waitForJobs();
-			System.out.println("Project still exists: " + i);
-		}
-	}
-
-
-	// ********** static methods **********
-
-	/**
-	 * Wait until all background tasks are complete.
-	 */
-	public static void waitForJobs() {
-		while (Job.getJobManager().currentJob() != null) {
-			try {
-				Thread.sleep(100);	// let other threads get something done
-			} catch (InterruptedException ex) {
-				throw new RuntimeException(ex);
-			}
-		}
-	}
-	
-}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/test.xml b/jpa/tests/org.eclipse.jpt.core.tests/test.xml
deleted file mode 100644
index 702dee3..0000000
--- a/jpa/tests/org.eclipse.jpt.core.tests/test.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-<project name="testsuite" default="run" basedir=".">
-	<!-- The property ${eclipse-home} should be passed into this script -->
-	<!-- Set a meaningful default value for when it is not. -->
-	<echo message="basedir ${basedir}" />
-	<echo message="eclipse place ${eclipse-home}" />
-	<!-- sets the properties plugin-name, and library-file -->
-	<property name="plugin-name" value="org.eclipse.jpt.core.tests"/>
-	<property name="library-file" value="${eclipse-home}/plugins/org.eclipse.test_3.1.0/library.xml"/>
-
-	<!-- This target holds all initialization code that needs to be done for -->
-	<!-- all tests that are to be run. Initialization for individual tests -->
-	<!-- should be done within the body of the suite target. -->
-	<target name="init">
-		<tstamp/>
-		<delete>
-			<fileset dir="${eclipse-home}" includes="org*.xml"/>
-		</delete>
-	</target>
-
-	<!-- This target defines the tests that need to be run. -->
-	<target name="suite">
-		<ant target="core-test" antfile="${library-file}" dir="${eclipse-home}">
-			<property name="plugin-name" value="${plugin-name}"/>
-			<property name="classname" value="org.eclipse.jpt.core.tests.internal.JptCoreTests" />
-			<property name="plugin-path" value="${eclipse-home}/plugins/${plugin-name}"/>
-		</ant>
-	</target>
-
-	<!-- This target holds code to cleanup the testing environment after -->
-	<!-- after all of the tests have been run. You can use this target to -->
-	<!-- delete temporary files that have been created. -->
-	<target name="cleanup">
-	</target>
-
-	<!-- This target runs the test suite. Any actions that need to happen -->
-	<!-- after all the tests have been run should go here. -->
-	<target name="run" depends="init,suite,cleanup">
-		<ant target="collect" antfile="${library-file}" dir="${eclipse-home}">
-			<property name="includes" value="org*.xml"/>
-			<property name="output-file" value="${plugin-name}.xml"/>
-		</ant>
-	</target>
-</project>
\ No newline at end of file
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/.classpath b/jpa/tests/org.eclipse.jpt.db.tests/.classpath
deleted file mode 100644
index 751c8f2..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/.cvsignore b/jpa/tests/org.eclipse.jpt.db.tests/.cvsignore
deleted file mode 100644
index ba077a4..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/.project b/jpa/tests/org.eclipse.jpt.db.tests/.project
deleted file mode 100644
index f5b0127..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>org.eclipse.jpt.db.tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/META-INF/MANIFEST.MF b/jpa/tests/org.eclipse.jpt.db.tests/META-INF/MANIFEST.MF
deleted file mode 100644
index eb01aca..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,16 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-Vendor: %providerName
-Bundle-SymbolicName: org.eclipse.jpt.db.tests
-Bundle-Version: 1.0.0.qualifier
-Bundle-Activator: org.eclipse.jpt.db.tests.internal.JptDbTestsPlugin
-Bundle-Localization: plugin
-Eclipse-LazyStart: false
-Require-Bundle: org.eclipse.core.runtime,
- org.junit,
- org.eclipse.datatools.connectivity,
- org.eclipse.datatools.connectivity.db.generic,
- org.eclipse.jpt.utility,
- org.eclipse.jpt.db
-Export-Package: org.eclipse.jpt.db.tests.internal.platforms
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/build.properties b/jpa/tests/org.eclipse.jpt.db.tests/build.properties
deleted file mode 100644
index cd0d010..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/build.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-source.. = src/
-output.. = bin/
-bin.includes = .,\
-               META-INF/,\
-               plugin.properties
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/config/derby101.properties b/jpa/tests/org.eclipse.jpt.db.tests/config/derby101.properties
deleted file mode 100644
index 6101413..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/config/derby101.properties
+++ /dev/null
@@ -1,30 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-#  Platform Property names & Default
-#
-#  profileName  - jpatest
-#  profileDescription  - JDBC Profile for JPA Testing
-#  userName  - jpatest
-#  userPassword  - (empty)
-#  databasedriverJarList  - (mandatory)
-#  databaseName  - testdb
-#  databaseUrl  - (mandatory)
-# 
-profileName = derby101
-profileDescription = Derby  Embedded JDBC Profile for Testing
-# set user name
-userName = jpatest
-userPassword =
-# set path to Derby driver here (example: databasedriverJarList = c:/derbydb/lib/derby.jar )
-databasedriverJarList = 
-databaseName = testdb
-# set database URL here (example: databaseUrl = jdbc:derby:c:/derbydb/testdb;create=true )  
-databaseUrl =
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/config/oracle10g.properties b/jpa/tests/org.eclipse.jpt.db.tests/config/oracle10g.properties
deleted file mode 100644
index 498fc7d..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/config/oracle10g.properties
+++ /dev/null
@@ -1,29 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-#  Platform Property names & Default
-#
-#  profileName  - jpatest
-#  profileDescription  - JDBC Profile for JPA Testing
-#  userName  - jpatest
-#  userPassword  - (empty)
-#  databasedriverJarList  - jar list separate by comma (mandatory) 
-#  databaseName  - testdb
-#  databaseUrl  - (mandatory)
-#
-profileName = oracleXE10g
-profileDescription = XE 10g Release 2 (10.2) Thin JDBC Profile for Testing
-userName = scott
-userPassword = tiger
-# set path to Oracle driver here (example: databasedriverJarList = c:/oracle/jdbc/lib/ojdbc14.jar )
-databasedriverJarList = 
-databaseName = testdb
-# set database URL here (example: databaseUrl = jdbc:oracle:thin:@localhost:1521:testdb )  
-databaseUrl = 
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/config/oracle9i.properties b/jpa/tests/org.eclipse.jpt.db.tests/config/oracle9i.properties
deleted file mode 100644
index 3207919..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/config/oracle9i.properties
+++ /dev/null
@@ -1,29 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-#  Platform Property names & Default
-#
-#  profileName  - jpatest
-#  profileDescription  - JDBC Profile for JPA Testing
-#  userName  - jpatest
-#  userPassword  - (empty)
-#  databasedriverJarList  - jar list separate by comma (mandatory) 
-#  databaseName  - testdb
-#  databaseUrl  - (mandatory)
-#
-profileName = oracle9i
-profileDescription = Oracle Thin JDBC Profile for Testing
-userName = scott
-userPassword = tiger
-# set path to Oracle driver here (example: databasedriverJarList = c:/oracle/jdbc/lib/ojdbc14.jar )
-databasedriverJarList =
-databaseName = testdb
-# set database URL here (example: databaseUrl = jdbc:oracle:thin:@server:1521:testdb )  
-databaseUrl =
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/config/sqlserver2005.properties b/jpa/tests/org.eclipse.jpt.db.tests/config/sqlserver2005.properties
deleted file mode 100644
index 8451351..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/config/sqlserver2005.properties
+++ /dev/null
@@ -1,30 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-#  Platform Property names & Default
-#
-#  profileName  - jpatest
-#  profileDescription  - JDBC Profile for JPA Testing
-#  userName  - jpatest
-#  userPassword  - (empty)
-#  databasedriverJarList  - (mandatory)
-#  databaseName  - testdb
-#  databaseUrl  - (mandatory)
-# 
-profileName = sqlserver2005
-profileDescription = MS SQL Server 2005 JDBC Profile for Testing
-# set user name
-userName = 
-userPassword = 
-# set path to Derby driver here (example: databasedriverJarList = c:/sqlserver/lib/sqljdbc.jar )
-databasedriverJarList = 
-databaseName = testdb
-# set database URL here (example: databaseUrl = jdbc:sqlserver://localhost:1433;databaseName=testdb )  
-databaseUrl = 
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/plugin.properties b/jpa/tests/org.eclipse.jpt.db.tests/plugin.properties
deleted file mode 100644
index b04fe27..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/plugin.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-###############################################################################
-#  Copyright (c) 2007 Oracle. 
-#  All rights reserved.  This program and the accompanying materials 
-#  are made available under the terms of the Eclipse Public License v1.0 
-#  which accompanies this distribution, and is available at 
-#  http://www.eclipse.org/legal/epl-v10.html
-#  
-#  Contributors: 
-#  	Oracle - initial API and implementation
-###############################################################################
-# ====================================================================
-# To code developer:
-#   Do NOT change the properties between this line and the
-#   "%%% END OF TRANSLATED PROPERTIES %%%" line.
-#   Make a new property name, append to the end of the file and change
-#   the code to use the new property.
-# ====================================================================
-
-# ====================================================================
-# %%% END OF TRANSLATED PROPERTIES %%%
-# ====================================================================
-
-pluginName = JPA DB Tests
-providerName = Eclipse.org
-
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/JptDbTests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/JptDbTests.java
deleted file mode 100644
index 2326ea3..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/JptDbTests.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.swingui.TestRunner;
-import org.eclipse.jpt.db.tests.internal.platforms.AllPlatformTests;
-import org.eclipse.jpt.utility.internal.ClassTools;
-
-/**
- *  JptDbTests
- */
-public class JptDbTests {
-
-    public static void main( String[] args) {
-        TestRunner.main( new String[] { "-c", JptDbTests.class.getName()});
-    }
-    
-    public static Test suite() {
-        TestSuite suite = new TestSuite( ClassTools.packageNameFor( JptDbTests.class));
-    
-        suite.addTest( AllPlatformTests.suite());
-    
-        return suite;
-    }
-    
-    private JptDbTests() {
-        super();
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/JptDbTestsPlugin.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/JptDbTestsPlugin.java
deleted file mode 100644
index dfced34..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/JptDbTestsPlugin.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal;
-
-import org.eclipse.core.runtime.Plugin;
-import org.osgi.framework.BundleContext;
-
-/**
- *  JptDbTestsPlugin
- */
-public class JptDbTestsPlugin extends Plugin {
-
-	// The shared instance
-	private static JptDbTestsPlugin plugin;
-
-	public static final String BUNDLE_ID = "org.eclipse.jpt.db.tests"; //$NON-NLS-1$
-
-	/**
-	 * Returns the shared instance
-	 */
-	public static JptDbTestsPlugin getDefault() {
-		return plugin;
-	}
-	
-	/**
-	 * The constructor
-	 */
-	public JptDbTestsPlugin() {
-		super();
-		plugin = this;
-	}
-
-	/**
-	 * This method is called upon plug-in activation
-	 */
-	public void start(BundleContext context) throws Exception {
-		super.start(context);
-	}
-
-	/**
-	 * This method is called when the plug-in is stopped
-	 */
-	public void stop(BundleContext context) throws Exception {
-		plugin = null;
-		super.stop(context);
-	}
-}
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/AllPlatformTests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/AllPlatformTests.java
deleted file mode 100644
index af9c423..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/AllPlatformTests.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal.platforms;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.swingui.TestRunner;
-import org.eclipse.jpt.utility.internal.ClassTools;
-
-/**
- *  AllPlatformTests
- */
-public class AllPlatformTests {
-
-    public static void main( String[] args) {
-        TestRunner.main( new String[] { "-c",  AllPlatformTests.class.getName()});
-    }
-
-    public static Test suite() {
-        TestSuite suite = new TestSuite( ClassTools.packageNameFor( AllPlatformTests.class));
-
-        // TODO - Uncomment the platform to test.
-//        suite.addTest( Derby101Tests.suite());
-//        suite.addTest( Oracle9iTests.suite());
-//        suite.addTest( Oracle10gTests.suite());
-//        suite.addTest( SQLServer2005Tests.suite());
-
-        return suite;
-    }
-
-    private AllPlatformTests() {
-        super();
-    }
-
-}
\ No newline at end of file
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/DTPPlatformTests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/DTPPlatformTests.java
deleted file mode 100644
index 46deffc..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/DTPPlatformTests.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 - 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal.platforms;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.NoSuchElementException;
-import java.util.Properties;
-import junit.framework.Assert;
-import junit.framework.TestCase;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.datatools.connectivity.ConnectionProfileException;
-import org.eclipse.datatools.connectivity.IConnectionProfile;
-import org.eclipse.datatools.connectivity.ProfileManager;
-import org.eclipse.datatools.connectivity.db.generic.IDBDriverDefinitionConstants;
-import org.eclipse.datatools.connectivity.drivers.IDriverMgmtConstants;
-import org.eclipse.datatools.connectivity.drivers.IPropertySet;
-import org.eclipse.datatools.connectivity.drivers.PropertySetImpl;
-import org.eclipse.datatools.connectivity.drivers.XMLFileManager;
-import org.eclipse.datatools.connectivity.internal.ConnectivityPlugin;
-import org.eclipse.jpt.db.internal.Connection;
-import org.eclipse.jpt.db.internal.ConnectionProfile;
-import org.eclipse.jpt.db.internal.ConnectionProfileRepository;
-import org.eclipse.jpt.db.internal.DTPConnectionProfileWrapper;
-import org.eclipse.jpt.db.internal.Database;
-import org.eclipse.jpt.db.internal.Schema;
-import org.eclipse.jpt.db.internal.Table;
-import org.eclipse.jpt.db.tests.internal.JptDbTestsPlugin;
-import org.eclipse.jpt.utility.internal.CollectionTools;
-import org.eclipse.jpt.utility.internal.StringTools;
-
-/**
- *  Base class for all supported DTP platform.
- */
-public abstract class DTPPlatformTests extends TestCase {
-
-    protected ConnectionProfileRepository connectionRepository;
-    
-    private Properties platformProperties;
-	private String currentDbVendor;
-	private String currentDbVersion;
-
-	private static final String PLATFORM_CONFIG_DIRECTORY = "config";	//$NON-NLS-1$
-	
-	private static final String PROFILE_NAME_PROPERTY = "profileName";	//$NON-NLS-1$
-	private static final String PROFILE_DESCRIPTION_PROPERTY = "profileDescription";	//$NON-NLS-1$
-	private static final String USER_NAME_PROPERTY = "userName";	//$NON-NLS-1$
-	private static final String USER_PASSWORD_PROPERTY = "userPassword";	//$NON-NLS-1$
-	private static final String DB_DRIVER_JAR_PROPERTY = "databasedriverJarList";	//$NON-NLS-1$
-	private static final String DB_NAME_PROPERTY = "databaseName";	//$NON-NLS-1$
-	private static final String DB_URL_PROPERTY = "databaseUrl";	//$NON-NLS-1$
-	
-	private static final String PROFILE_NAME_DEFAULT = "jpatest";	//$NON-NLS-1$
-	private static final String PROFILE_DESCRIPTION_DEFAULT = "JDBC Profile for JPA Testing";	//$NON-NLS-1$
-	private static final String USER_NAME_DEFAULT = "userName";	//$NON-NLS-1$
-	private static final String USER_PASSWORD_DEFAULT = "";	//$NON-NLS-1$
-	private static final String DB_NAME_DEFAULT = "testdb";	//$NON-NLS-1$
-	
-	private static final String MISSING_PROPERTY_MESSAGE = "Enter missing property in platform config file (config/database.properties)";	
-
-    public DTPPlatformTests( String name) {
-        super( name);
-        
-        this.connectionRepository = ConnectionProfileRepository.instance();
-    }
-
-	protected void setUp() throws Exception {
-        super.setUp();
-        this.connectionRepository.initializeListeners();
-        
-        if( this.platformIsNew()) {
-        	this.loadPlatformProperties();
-        	
-        	this.buildDriverDefinitionFile( IDriverMgmtConstants.DRIVER_FILE);
-        	this.buildConnectionProfile( this.profileName());
-        	this.currentDbVendor = this.databaseVendor();
-        	this.currentDbVersion = this.databaseVersion();
-        }
-        this.verifyProfileNamed( this.profileName());
-	}
-
-	protected void tearDown() throws Exception {
-        super.tearDown();
-        
-        this.connectionRepository.disposeListeners();
-	}
-
-	// ********** tests **********
-
-	public void testConnection() throws Exception {
-
-		this.connect();
-		
-        this.verifyDatabaseVersionNumber();
-        this.verifyConnection();
-        this.verifyDatabaseContent();
-
-        this.disconnect();
-    }
-    
-	public void testGetProfiles() {
-		// Getting the profile directly from DTP ProfileManager
-		IConnectionProfile[] profiles = ProfileManager.getInstance().getProfiles();
-		Assert.assertNotNull( profiles);
-		Assert.assertTrue( profiles.length > 0);
-	}
-
-	public void testGetProfilesByProvider() {
-		// Get Profiles By ProviderID
-		IConnectionProfile[] profiles = ProfileManager.getInstance().getProfileByProviderID( this.getProfile().getProviderId());
-		Assert.assertNotNull( profiles);
-		Assert.assertTrue( profiles.length > 0);
-	}
-	
-	public void testGetProfileByName() {
-		// Get Profile By Name
-		IConnectionProfile dtpProfile = ProfileManager.getInstance().getProfileByName( this.profileName());
-		Assert.assertNotNull( dtpProfile);
-		Assert.assertTrue( dtpProfile.getName().equals( this.profileName()));
-	}
-	
-	public void testGetProfileByInstanceId() {
-		// Get Profile By InstanceID
-		IConnectionProfile dtpProfile = ProfileManager.getInstance().getProfileByInstanceID( this.getProfile().getInstanceId());
-		Assert.assertNotNull( dtpProfile);
-		Assert.assertTrue( dtpProfile.getName().equals( this.profileName()));
-	}
-
-	// ********** internal tests **********
-
-    private void verifyDatabaseVersionNumber() {
-    	Database database = this.getProfile().getDatabase();
-    	Assert.assertNotNull( database);
-    	
-        String actualVersionNumber = database.getVersion();
-        String expectedVersionNumber = this.databaseVersion();
-        String errorMessage = "Expected version number: " + expectedVersionNumber + " but the actual version number was: " + actualVersionNumber;
-        assertTrue( errorMessage, actualVersionNumber.indexOf( expectedVersionNumber) != -1);
-
-        String actualVendor = database.getVendor();
-        String expectedVendor = this.databaseVendor();
-        errorMessage = "Expected vendor: " + expectedVendor + " but the actual vendor was: " + actualVendor;
-        assertEquals( errorMessage, actualVendor, expectedVendor);
-    }
-    
-    private void verifyConnection() {
-    	Connection connection = this.getProfile().getConnection();
-    	Assert.assertNotNull( connection);
-
-        String actualFactory = connection.getFactoryId();
-        String expectedFactory = DTPConnectionProfileWrapper.CONNECTION_TYPE;
-    	String errorMessage = "Expected factory: " + expectedFactory + " but the actual factory was: " + actualFactory;
-    	assertEquals( errorMessage, actualFactory, expectedFactory);
-    }
-    
-    private void verifyDatabaseContent() {
-    	Database database = this.getProfile().getDatabase();
-    	Assert.assertTrue( database.schemataSize() > 0);
-		
-        Schema schema = database.schemaNamed( this.getProfile().getUserName());
-		if( schema != null) {
-			Assert.assertTrue( schema.sequencesSize() >= 0);
-			
-			Object[] tableNames = CollectionTools.array( schema.tableNames());
-			if( tableNames.length >= 1) {
-				Table table = schema.tableNamed(( String)tableNames[ 0]);
-				Assert.assertTrue( table.columnsSize() >= 0);
-				Assert.assertTrue( table.foreignKeyColumnsSize() >= 0);
-				Assert.assertTrue( table.foreignKeysSize() >= 0);
-				Assert.assertTrue( table.primaryKeyColumnsSize() >= 0);
-			}
-		}
-    }
-
-    private void verifyProfileNamed( String profileName) {
-    	
-    	ConnectionProfile profile = this.getProfileNamed( profileName);
-    	Assert.assertTrue( "ConnectionProfile not found", profileName.equals( profile.getName()));
-    }
-
-	// ***** Platform specific behavior *****
-
-    protected abstract String databaseVendor();
-    protected abstract String databaseVersion();
-
-    protected abstract String driverName();
-    protected abstract String driverDefinitionType();
-    protected abstract String driverDefinitionId();
-    protected abstract String driverClass();
-
-    protected abstract String getConfigName();
-
-	// ***** Behavior *****
-
-    protected void connect() {
-
-        this.getProfile().connect();
-		Assert.assertTrue( "Connect failed.", this.getProfile().isConnected());
-    }
-    
-    protected void disconnect() {
-    	
-    	this.getProfile().disconnect();
-        Assert.assertFalse( "Disconnect failed.", this.getProfile().isConnected());
-    }
-    
-	// ********** queries **********
-
-    protected Schema getSchemaNamed( String schemaName) { 
-
-	    return this.getProfile().getDatabase().schemaNamed( schemaName);
-    }
-	
-    protected Collection getTables() {
-		
-        Schema schema = this.getSchemaNamed( this.getProfile().getUserName());
-		if( schema == null) {
-			return new ArrayList();
-		}
-		return CollectionTools.collection( schema.tables());
-    }
-
-    protected Table getTableNamed( String tableName) { 
-
-	    Schema schema =  this.getSchemaNamed( this.getProfile().getUserName());
-	    Assert.assertNotNull( schema);
-	
-		return schema.tableNamed( tableName);
-    }
-
-    protected String providerId() {
-        return DTPConnectionProfileWrapper.CONNECTION_PROFILE_TYPE;
-    }
-     
-    protected String passwordIsSaved() {
-        return "true";
-    }
-	
-    protected String profileName() {
-    	return this.platformProperties.getProperty( PROFILE_NAME_PROPERTY, PROFILE_NAME_DEFAULT);
-    }    
-    
-    protected String profileDescription() {
-    	return this.platformProperties.getProperty( PROFILE_DESCRIPTION_PROPERTY, PROFILE_DESCRIPTION_DEFAULT);
-    }    
-    
-    protected String userName() {
-    	return this.platformProperties.getProperty( USER_NAME_PROPERTY, USER_NAME_DEFAULT);
-    }
-    
-    protected String userPassword() {
-    	return this.platformProperties.getProperty( USER_PASSWORD_PROPERTY, USER_PASSWORD_DEFAULT);
-    }    
-    
-    protected String databaseName() {
-    	return this.platformProperties.getProperty( DB_NAME_PROPERTY, DB_NAME_DEFAULT);
-    }
-    
-    protected String databasedriverJarList() {
-    	String dbDriverJarList = this.platformProperties.getProperty( DB_DRIVER_JAR_PROPERTY);
-    	if ( StringTools.stringIsEmpty( dbDriverJarList)) {
-    		throw new NoSuchElementException( MISSING_PROPERTY_MESSAGE);
-    	}
-    	return dbDriverJarList;
-    }
-    
-    protected String databaseUrl() {
-    	String dbUrl = this.platformProperties.getProperty( DB_URL_PROPERTY);
-    	if ( StringTools.stringIsEmpty( dbUrl)) {
-    		throw new NoSuchElementException( MISSING_PROPERTY_MESSAGE);
-    	}
-    	return dbUrl;
-    }
-
-    private ConnectionProfile getProfile() {
-
-    	return this.getProfileNamed( this.profileName());
-    }
-
-    protected ConnectionProfile getProfileNamed( String profileName) {
-    	
-    	return ConnectionProfileRepository.instance().profileNamed( profileName);
-    }
-   
-    private String getTestPluginBundleId() {
-		return JptDbTestsPlugin.BUNDLE_ID;
-	}
-
-	private IPath getDriverDefinitionLocation() {
-		return ConnectivityPlugin.getDefault().getStateLocation();
-	}
-	
-	private String getConfigPath() {
-    	return this.getConfigDir() + "/" + this.getConfigName();
-    }
-	
-	private String getConfigDir() {
-    	return PLATFORM_CONFIG_DIRECTORY;
-    }
-
-	private boolean platformIsNew() {
-		return( !this.databaseVendor().equals( this.currentDbVendor) || this.databaseVersion().equals( this.currentDbVersion));
-	}
-	
-    private void loadPlatformProperties() throws IOException {
-		
-		if( this.platformProperties == null) {
-			URL configUrl = Platform.getBundle( this.getTestPluginBundleId()).getEntry( this.getConfigPath());
-
-			this.platformProperties = new Properties();
-			this.platformProperties.load( configUrl.openStream());
-		}
-	}
-	
-	private Properties buildDriverProperties() {
-		Properties driverProperties = new Properties();
-		driverProperties.setProperty( DTPConnectionProfileWrapper.DRIVER_DEFINITION_TYPE_PROP_ID, this.driverDefinitionType());
-		driverProperties.setProperty( DTPConnectionProfileWrapper.DRIVER_JAR_LIST_PROP_ID, this.databasedriverJarList());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.USERNAME_PROP_ID, this.userName());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.DRIVER_CLASS_PROP_ID, this.driverClass());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_NAME_PROP_ID, this.databaseName());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.PASSWORD_PROP_ID, this.userPassword());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.URL_PROP_ID, this.databaseUrl());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID, this.databaseVendor());
-		driverProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VERSION_PROP_ID, this.databaseVersion());
-		return driverProperties;
-	}
-
-	private Properties buildBasicProperties() {
-		Properties basicProperties = new Properties();
-		basicProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_NAME_PROP_ID, this.databaseName());
-		basicProperties.setProperty( IDBDriverDefinitionConstants.USERNAME_PROP_ID, this.userName());
-		basicProperties.setProperty( IDBDriverDefinitionConstants.PASSWORD_PROP_ID, this.userPassword());
-		basicProperties.setProperty( DTPConnectionProfileWrapper.DRIVER_DEFINITION_PROP_ID, this.driverDefinitionId());
-		
-		basicProperties.setProperty( IDBDriverDefinitionConstants.DRIVER_CLASS_PROP_ID, this.driverClass());
-		basicProperties.setProperty( IDBDriverDefinitionConstants.URL_PROP_ID, this.databaseUrl());
-		basicProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID, this.databaseVendor());
-		basicProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VERSION_PROP_ID, this.databaseVersion());
-		
-		basicProperties.setProperty( DTPConnectionProfileWrapper.DATABASE_SAVE_PWD_PROP_ID, this.passwordIsSaved());
-		return basicProperties;
-	}
-
-	private void buildConnectionProfile( String profileName) throws ConnectionProfileException {
-		
-		ProfileManager profileManager = ProfileManager.getInstance();
-		Assert.assertNotNull( profileManager);
-		IConnectionProfile profile = profileManager.getProfileByName( profileName);
-		if( profile == null) {
-			Properties basicProperties = buildBasicProperties();
-			ProfileManager.getInstance().createProfile( profileName, this.profileDescription(), this.providerId(), basicProperties);
-		}
-	}
-
-	private void buildDriverDefinitionFile( String driverFileName) throws CoreException {
-		
-		XMLFileManager.setStorageLocation( this.getDriverDefinitionLocation());
-		XMLFileManager.setFileName( driverFileName);
-		IPropertySet[] propsets = new IPropertySet[ 1];
-		String driverName = this.driverName();
-		String driverId = this.driverDefinitionId();
-		PropertySetImpl propertySet = new PropertySetImpl( driverName, driverId);
-		propertySet.setProperties( driverId, this.buildDriverProperties());
-		propsets[ 0] = propertySet;
-
-		XMLFileManager.saveNamedPropertySet( propsets);
-		
-		File driverDefinitioneFile =  this.getDriverDefinitionLocation().append( driverFileName).toFile();
-		Assert.assertTrue( driverDefinitioneFile.exists());
-	}
-	
-}
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Derby101Tests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Derby101Tests.java
deleted file mode 100644
index 7e510cf..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Derby101Tests.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal.platforms;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.swingui.TestRunner;
-
-/**
- *  Derby 10.1 Embedded Driver Test
- */
-public class Derby101Tests extends DTPPlatformTests {
-	
-    public static void main( String[] args) {
-        TestRunner.main( new String[] { "-c", Derby101Tests.class.getName()});
-    }
-
-    public static Test suite() {
-        return new TestSuite( Derby101Tests.class);
-    }
-    
-    public Derby101Tests( String name) {
-        super( name);
-    }
-    
-    protected String databaseVendor() {
-        return "Derby";
-    }
-
-    protected String databaseVersion() {
-        return "10.1";
-    }
-	
-    protected String providerId() {
-        return "org.eclipse.datatools.connectivity.db.derby.embedded.connectionProfile";
-    }
-    
-    protected String driverName() {
-        return "Derby Embedded JDBC Driver";
-    }
-    
-    protected String driverDefinitionType() {
-        return "org.eclipse.datatools.connectivity.db.derby101.genericDriverTemplate";
-    }
-    
-    protected String driverDefinitionId() {
-        return "DriverDefn.Derby Embedded JDBC Driver";
-    }
-    
-    protected String driverClass() {
-        return "org.apache.derby.jdbc.EmbeddedDriver";
-    }
-	
-    protected String getConfigName() {
-    	return "derby101.properties";
-    }
-}
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Oracle10gTests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Oracle10gTests.java
deleted file mode 100644
index 70d3a3d..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Oracle10gTests.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal.platforms;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.swingui.TestRunner;
-
-/**
- *  Oracle 10g Thin Driver Test
- */
-public class Oracle10gTests extends DTPPlatformTests {
-
-    public static void main( String[] args) {
-        TestRunner.main( new String[] { "-c", Oracle10gTests.class.getName()});
-    }
-
-    public static Test suite() {
-        return new TestSuite( Oracle10gTests.class);
-    }
-    
-    public Oracle10gTests( String name) {
-        super( name);
-    }
-
-	protected String databaseVendor() {
-		return "Oracle";
-	}
-
-	protected String databaseVersion() {
-		return "10";
-	}
-
-	protected String driverClass() {
-		return "oracle.jdbc.OracleDriver";
-	}
-
-	protected String driverDefinitionId() {
-		return "DriverDefn.Oracle Thin Driver";
-	}
-
-	protected String driverDefinitionType() {
-		return "org.eclipse.datatools.enablement.oracle.10.driverTemplate";
-	}
-
-	protected String driverName() {
-		return "Oracle 10g Thin Driver";
-	}
-	
-    protected String getConfigName() {
-    	return "oracle10g.properties";
-    }
-}
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Oracle9iTests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Oracle9iTests.java
deleted file mode 100644
index 3923081..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/Oracle9iTests.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006, 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal.platforms;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.swingui.TestRunner;
-
-/**
- *  Oracle 9i Thin Driver Test
- */
-public class Oracle9iTests extends DTPPlatformTests {
-
-    public static void main( String[] args) {
-        TestRunner.main( new String[] { "-c", Oracle9iTests.class.getName()});
-    }
-
-    public static Test suite() {
-        return new TestSuite( Oracle9iTests.class);
-    }
-    
-    public Oracle9iTests( String name) {
-        super( name);
-    }
-
-	protected String databaseVendor() {
-		return "Oracle";
-	}
-
-	protected String databaseVersion() {
-		return "9";
-	}
-
-	protected String driverClass() {
-		return "oracle.jdbc.OracleDriver";
-	}
-
-	protected String driverDefinitionId() {
-		return "DriverDefn.Oracle Thin Driver";
-	}
-
-	protected String driverDefinitionType() {
-		return "org.eclipse.datatools.enablement.oracle.9.driverTemplate";
-	}
-
-	protected String driverName() {
-		return "Oracle 9i Thin Driver";
-	}
-	
-    protected String getConfigName() {
-    	return "oracle9i.properties";
-    }
-}
diff --git a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/SQLServer2005Tests.java b/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/SQLServer2005Tests.java
deleted file mode 100644
index a0f5034..0000000
--- a/jpa/tests/org.eclipse.jpt.db.tests/src/org/eclipse/jpt/db/tests/internal/platforms/SQLServer2005Tests.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the terms of
- * the Eclipse Public License v1.0, which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html.
- *
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.db.tests.internal.platforms;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.swingui.TestRunner;
-
-/**
- *  SQL Server 2005 Driver Test
- */
-public class SQLServer2005Tests extends DTPPlatformTests {
-	
-    public static void main( String[] args) {
-        TestRunner.main( new String[] { "-c", SQLServer2005Tests.class.getName()});
-    }
-
-    public static Test suite() {
-        return new TestSuite( SQLServer2005Tests.class);
-    }
-    
-    public SQLServer2005Tests( String name) {
-        super( name);
-    }
-    
-    protected String databaseVendor() {
-        return "SQLServer";
-    }
-
-    protected String databaseVersion() {
-        return "2005";
-    }
-	
-    protected String providerId() {
-        return "org.eclipse.datatools.connectivity.db.generic.connectionProfile";
-    }
-    
-    protected String driverName() {
-        return "Microsoft SQL Server 2005 JDBC Driver";
-    }
-    
-    protected String driverDefinitionType() {
-        return "org.eclipse.datatools.enablement.msft.sqlserver.2005.driverTemplate";
-    }
-    
-    protected String driverDefinitionId() {
-        return "DriverDefn.Microsoft SQL Server 2005 JDBC Driver";
-    }
-    
-    protected String driverClass() {
-        return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
-    }
-	
-    protected String getConfigName() {
-    	return "sqlserver2005.properties";
-    }
-}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/.cvsignore b/jpa/tests/org.eclipse.jpt.utility.tests/.cvsignore
index ba077a4..c4ba612 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/.cvsignore
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/.cvsignore
@@ -1 +1,5 @@
 bin
+@dot
+temp.folder
+build.xml
+javaCompiler...args
\ No newline at end of file
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/BitToolsTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/BitToolsTests.java
index ed3e6f2..8f2e9b8 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/BitToolsTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/BitToolsTests.java
@@ -18,6 +18,61 @@
 		super(name);
 	}
 
+	public void testFlagIsSetIntInt() {
+		assertTrue(BitTools.flagIsSet(0x0003, 0x0001));
+		assertTrue(BitTools.flagIsSet(0x0303, 0x0001));
+		assertTrue(BitTools.flagIsSet(0x0303, 0x0101));
+		assertTrue(BitTools.flagIsSet(0x0303, 0x0103));
+
+		assertFalse(BitTools.flagIsSet(0x0303, 0x1103));
+		assertFalse(BitTools.flagIsSet(0x0000, 0x1103));
+	}
+
+	public void testFlagIsOffIntInt() {
+		assertFalse(BitTools.flagIsOff(0x0003, 0x0001));
+		assertFalse(BitTools.flagIsOff(0x0303, 0x0001));
+		assertFalse(BitTools.flagIsOff(0x0303, 0x0101));
+		assertFalse(BitTools.flagIsOff(0x0303, 0x0103));
+
+		assertTrue(BitTools.flagIsOff(0x2204, 0x1103));
+		assertTrue(BitTools.flagIsOff(0x0000, 0x1103));
+	}
+
+	public void testOnlyFlagIsSetIntInt() {
+		assertFalse(BitTools.onlyFlagIsSet(0x0003, 0x0001));
+		assertTrue(BitTools.onlyFlagIsSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagIsSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagIsSet(0x0101, 0x0101));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagIsSet(0x0103, 0x0103));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagIsSet(0x1103, 0x1103));
+
+		assertFalse(BitTools.onlyFlagIsSet(0x0000, 0x1103));
+		assertTrue(BitTools.onlyFlagIsSet(0x0103, 0x0103));
+	}
+
+	public void testOnlyFlagIsOffIntInt() {
+		assertFalse(BitTools.onlyFlagIsOff(0x0003, 0x0001));
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFFFE, 0x0001));
+
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFEFE, 0x0101));
+
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFFEFC, 0x0103));
+
+		assertFalse(BitTools.onlyFlagIsOff(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagIsOff(0xFFFFEEFC, 0x1103));
+	}
+
 	public void testAllFlagsAreSetIntInt() {
 		assertTrue(BitTools.allFlagsAreSet(0x0003, 0x0001));
 		assertTrue(BitTools.allFlagsAreSet(0x0303, 0x0001));
@@ -28,6 +83,69 @@
 		assertFalse(BitTools.allFlagsAreSet(0x0000, 0x1103));
 	}
 
+	public void testAllFlagsAreOffIntInt() {
+		assertFalse(BitTools.allFlagsAreOff(0x0003, 0x0001));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0001));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0101));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, 0x0103));
+
+		assertTrue(BitTools.allFlagsAreOff(0x2204, 0x1103));
+		assertTrue(BitTools.allFlagsAreOff(0x0000, 0x1103));
+	}
+
+	public void testOnlyFlagsAreSetIntInt() {
+		assertFalse(BitTools.onlyFlagsAreSet(0x0003, 0x0001));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, 0x0001));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0101, 0x0101));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, 0x0103));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagsAreSet(0x1103, 0x1103));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0000, 0x1103));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, 0x0103));
+	}
+
+	public void testOnlyFlagsAreOffIntInt() {
+		assertFalse(BitTools.onlyFlagsAreOff(0x0003, 0x0001));
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0001));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFFFE, 0x0001));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0101));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFE, 0x0101));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x0103));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFC, 0x0103));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, 0x1103));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFEEFC, 0x1103));
+	}
+
+	public void testAnyFlagsAreSetIntInt() {
+		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0x0001));
+		assertTrue(BitTools.anyFlagsAreSet(0xFFFF, 0x0001));
+		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0xFFFF));
+
+		assertFalse(BitTools.anyFlagsAreSet(0x0303, 0x1010));
+		assertFalse(BitTools.anyFlagsAreSet(0x0000, 0xFFFF));
+	}
+
+	public void testAnyFlagsAreOffIntInt() {
+		assertTrue(BitTools.anyFlagsAreOff(0x333E, 0x0001));
+		assertTrue(BitTools.anyFlagsAreOff(0xFFFE, 0x0001));
+		assertTrue(BitTools.anyFlagsAreOff(0x0003, 0xFFFF));
+
+		assertFalse(BitTools.anyFlagsAreOff(0x7373, 0x1010));
+		assertFalse(BitTools.anyFlagsAreOff(0xFFFF, 0xFFFF));
+	}
+
 	public void testAllFlagsAreSetIntIntArray() {
 		assertTrue(BitTools.allFlagsAreSet(0x0003, new int[] { 0x0001 }));
 		assertTrue(BitTools.allFlagsAreSet(0x0303, new int[] { 0x0001 }));
@@ -38,13 +156,49 @@
 		assertFalse(BitTools.allFlagsAreSet(0x0000, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
 	}
 
-	public void testAnyFlagsAreSetIntInt() {
-		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0x0001));
-		assertTrue(BitTools.anyFlagsAreSet(0xFFFF, 0x0001));
-		assertTrue(BitTools.anyFlagsAreSet(0x0003, 0xFFFF));
+	public void testAllFlagsAreOffIntIntArray() {
+		assertFalse(BitTools.allFlagsAreOff(0x0003, new int[] { 0x0001 }));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0001 }));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0100, 0x0001 }));
+		assertFalse(BitTools.allFlagsAreOff(0x0303, new int[] { 0x0100, 0x0002, 0x0001 }));
 
-		assertFalse(BitTools.anyFlagsAreSet(0x0303, 0x1010));
-		assertFalse(BitTools.anyFlagsAreSet(0x0000, 0xFFFF));
+		assertTrue(BitTools.allFlagsAreOff(0x0303, new int[] { 0x1000, 0x0400, 0x0020, 0x0000 }));
+		assertTrue(BitTools.allFlagsAreOff(0x0000, new int[] { 0x1000, 0x0100, 0x0002, 0x0001 }));
+	}
+
+	public void testOnlyFlagsAreSetIntIntArray() {
+		assertFalse(BitTools.onlyFlagsAreSet(0x0003, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0001, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0101, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0303, new int[] { 0x011, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x1103, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreSet(0x0000, new int[] { 0x011, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreSet(0x0103, new int[] { 0x0101, 0x0100, 0x0002, 0x0001 }));
+	}
+
+	public void testOnlyFlagsAreOffIntIntArray() {
+		assertFalse(BitTools.onlyFlagsAreOff(0x0003, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFFFE, new int[] { 0x001, 0x0000, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFE, new int[] { 0x001, 0x0100, 0x0000, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFFEFC, new int[] { 0x001, 0x0100, 0x0002, 0x0001 }));
+
+		assertFalse(BitTools.onlyFlagsAreOff(0x0303, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
+		assertTrue(BitTools.onlyFlagsAreOff(0xFFFFEEFC, new int[] { 0x1100, 0x0100, 0x0002, 0x0001 }));
 	}
 
 	public void testAnyFlagsAreSetIntIntArray() {
@@ -56,4 +210,34 @@
 		assertFalse(BitTools.anyFlagsAreSet(0x0000, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
 	}
 
+	public void testAnyFlagsAreOffIntIntArray() {
+		assertFalse(BitTools.anyFlagsAreOff(0x0003, new int[] { 0x0001 }));
+		assertFalse(BitTools.anyFlagsAreOff(0xFFFF, new int[] { 0x0001 }));
+		assertFalse(BitTools.anyFlagsAreOff(0x0303, new int[] { 0x0100, 0x0200, 0x0003, 0x0002 }));
+
+		assertTrue(BitTools.anyFlagsAreOff(0x0303, new int[] { 0x0100, 0x0010 }));
+		assertTrue(BitTools.anyFlagsAreOff(0x0000, new int[] { 0xF000, 0x0F00, 0x00F0, 0x000F }));
+	}
+
+	public void testOrFlags() {
+		assertEquals(0x0001, BitTools.orFlags(new int[] { 0x0001, 0x0000 }));
+		assertEquals(0x0011, BitTools.orFlags(new int[] { 0x0001, 0x0011 }));
+		assertEquals(0xF011, BitTools.orFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
+	}
+
+	public void testAndFlags() {
+		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0001 }));
+		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0011 }));
+		assertEquals(0x0000, BitTools.andFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
+		assertEquals(0x0001, BitTools.andFlags(new int[] { 0x0001, 0x0011, 0xF001 }));
+	}
+
+	public void testXorFlags() {
+		assertEquals(0x0001, BitTools.xorFlags(new int[] { 0x0001, 0x0000 }));
+		assertEquals(0x0010, BitTools.xorFlags(new int[] { 0x0001, 0x0011 }));
+		assertEquals(0xF010, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000 }));
+		assertEquals(0xFF11, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000, 0x0F01 }));
+		assertEquals(0xF010, BitTools.xorFlags(new int[] { 0x0001, 0x0011, 0xF000, 0x0F01, 0x0F01 }));
+	}
+
 }
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/CollectionToolsTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/CollectionToolsTests.java
index 0279840..7bd0a7d 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/CollectionToolsTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/CollectionToolsTests.java
@@ -105,6 +105,21 @@
 		assertTrue(Arrays.equals(new int[] { 1, 2, 99, 3, 4 }, a));
 	}
 
+	public void testAddAllCollectionIterable() {
+		List<String> l1 = this.buildStringList1();
+		Iterable<String> i2 = this.buildStringList2();
+		Set<String> s1 = this.buildStringSet1();
+		Iterable<String> i3 = this.buildStringList1(); // same elements as s1
+
+		assertTrue(CollectionTools.addAll(l1, i2.iterator()));
+		assertEquals(6, l1.size());
+		assertTrue(l1.containsAll(this.buildStringList2()));
+
+		assertFalse(CollectionTools.addAll(s1, i3.iterator()));
+		assertEquals(3, s1.size());
+		assertTrue(s1.containsAll(this.buildStringList1()));
+	}
+
 	public void testAddAllCollectionIterator1() {
 		List<String> l1 = this.buildStringList1();
 		List<String> l2 = this.buildStringList2();
@@ -181,6 +196,15 @@
 		assertTrue(CollectionTools.containsAll(newArray, c));
 	}
 
+	public void testAddAllObjectArrayIterable() {
+		String[] a = this.buildStringArray1();
+		Iterable<String> i = this.buildStringList1();
+		String[] newArray = CollectionTools.addAll(a, i);
+
+		assertEquals(6, newArray.length);
+		assertTrue(CollectionTools.containsAll(newArray, this.buildStringList1()));
+	}
+
 	public void testAddAllObjectArrayIterator1() {
 		String[] a = this.buildStringArray1();
 		Iterator<String> i = this.buildStringList1().iterator();
@@ -283,6 +307,27 @@
 		assertTrue(Arrays.equals(new int[] { 1, 2, 99, 99, 99, 3, 4 }, a));
 	}
 
+	public void testArrayIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Object[] a = CollectionTools.array(iterable);
+		assertEquals(3, a.length);
+		assertTrue(CollectionTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterableObjectArray1() {
+		Iterable<String> iterable = this.buildStringList1();
+		String[] a = CollectionTools.array(iterable, new String[0]);
+		assertEquals(3, a.length);
+		assertTrue(CollectionTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
+	public void testArrayIterableObjectArray2() {
+		Iterable<String> iterable = this.buildStringList1();
+		Object[] a = CollectionTools.array(iterable, new Object[0]);
+		assertEquals(3, a.length);
+		assertTrue(CollectionTools.containsAll(a, this.buildStringList1().iterator()));
+	}
+
 	public void testArrayIterator() {
 		Object[] a = CollectionTools.array(this.buildStringList1().iterator());
 		assertEquals(3, a.length);
@@ -313,6 +358,13 @@
 		assertTrue(b.containsAll(this.buildStringVector1()));
 	}
 
+	public void testBagIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Bag<String> b = CollectionTools.bag(iterable);
+		assertEquals(3, b.size());
+		assertTrue(b.containsAll(this.buildStringList1()));
+	}
+
 	public void testBagIterator1() {
 		Bag<String> b = CollectionTools.bag(this.buildStringList1().iterator());
 		assertEquals(3, b.size());
@@ -354,6 +406,13 @@
 		assertTrue(c.containsAll(this.buildStringVector1()));
 	}
 
+	public void testCollectionIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Collection<String> c = CollectionTools.collection(iterable);
+		assertEquals(3, c.size());
+		assertTrue(c.containsAll(this.buildStringList1()));
+	}
+
 	public void testCollectionIterator1() {
 		Collection<String> c = CollectionTools.collection(this.buildStringList1().iterator());
 		assertEquals(3, c.size());
@@ -393,6 +452,15 @@
 		assertTrue(CollectionTools.contains(c.elements(), null));
 	}
 
+	public void testContainsIterableObject() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = c;
+		assertTrue(CollectionTools.contains(iterable, "one"));
+		assertFalse(CollectionTools.contains(iterable, null));
+		c.add(null);
+		assertTrue(CollectionTools.contains(iterable, null));
+	}
+
 	public void testContainsIteratorObject1() {
 		Collection<String> c = this.buildStringList1();
 		assertTrue(CollectionTools.contains(c.iterator(), "one"));
@@ -438,6 +506,11 @@
 		assertTrue(CollectionTools.contains(a2, 55));
 	}
 
+	public void testContainsAllCollectionIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(this.buildStringList1(), iterable));
+	}
+
 	public void testContainsAllCollectionIterator1() {
 		assertTrue(CollectionTools.containsAll(this.buildStringList1(), this.buildStringList1().iterator()));
 	}
@@ -463,6 +536,27 @@
 		assertTrue(CollectionTools.containsAll(this.buildStringList1(), a));
 	}
 
+	public void testContainsAllIterableCollection() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(iterable, this.buildStringList1()));
+	}
+
+	public void testContainsAllIterableIterable() {
+		Iterable<String> iterable1 = this.buildStringList1();
+		Iterable<String> iterable2 = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(iterable1, iterable2));
+	}
+
+	public void testContainsAllIterableIterator() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(iterable, this.buildStringList1().iterator()));
+	}
+
+	public void testContainsAllIterableObjectArray() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(iterable, this.buildObjectArray1()));
+	}
+
 	public void testContainsAllIteratorCollection1() {
 		assertTrue(CollectionTools.containsAll(this.buildStringList1().iterator(), this.buildStringList1()));
 	}
@@ -507,6 +601,11 @@
 		assertTrue(CollectionTools.containsAll(this.buildObjectArray1(), this.buildStringList1().iterator()));
 	}
 
+	public void testContainsAllObjectArrayIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.containsAll(this.buildObjectArray1(), iterable));
+	}
+
 	public void testContainsAllObjectArrayObjectArray() {
 		assertTrue(CollectionTools.containsAll(this.buildObjectArray1(), this.buildObjectArray1()));
 	}
@@ -1150,6 +1249,14 @@
 		assertEquals(6, CollectionTools.insertionIndexOf(a, "A", c));
 	}
 
+	public void testIterableObjectArray() {
+		String[] strings = this.buildStringArray1();
+		int i = 0;
+		for (String string : CollectionTools.iterable(strings)) {
+			assertEquals(strings[i++], string);
+		}
+	}
+
 	public void testIteratorObjectArray() {
 		String[] a = this.buildStringArray1();
 		int i = 0;
@@ -1186,6 +1293,11 @@
 		assertEquals(a.length - 1, CollectionTools.lastIndexOf(a, 30));
 	}
 
+	public void testListIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		assertEquals(this.buildStringList1(), CollectionTools.list(iterable));
+	}
+
 	public void testListIterator1() {
 		List<String> list = CollectionTools.list(this.buildStringList1().iterator());
 		assertEquals(this.buildStringList1(), list);
@@ -1239,6 +1351,183 @@
 		assertEquals(0, CollectionTools.min(this.buildIntArray()));
 	}
 
+	public void testMoveObjectArrayIntInt() {
+		String[] array = new String[] { "0", "1", "2", "3", "4", "5" };
+
+		String[] result = CollectionTools.move(array, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result));
+
+		result = CollectionTools.move(array, 0, 5);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result));
+
+		result = CollectionTools.move(array, 2, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
+	}
+
+	public void testMoveObjectArrayIntIntInt() {
+		String[] array = new String[] { "0", "1", "2", "3", "4", "5" };
+
+		String[] result = CollectionTools.move(array, 4, 2, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result));
+
+		result = CollectionTools.move(array, 0, 5, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result));
+
+		result = CollectionTools.move(array, 2, 4, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result));
+
+		result = CollectionTools.move(array, 2, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
+
+		result = CollectionTools.move(array, 0, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result));
+
+		result = CollectionTools.move(array, 1, 0, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result));
+	}
+
+	public void testMoveIntArrayIntInt() {
+		int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
+
+		int[] result = CollectionTools.move(array, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 0, 1, 3, 4, 2, 5 }, result));
+
+		result = CollectionTools.move(array, 0, 5);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 1, 3, 4, 2 }, result));
+
+		result = CollectionTools.move(array, 2, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
+	}
+
+	public void testMoveInttArrayIntIntInt() {
+		int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
+
+		int[] result = CollectionTools.move(array, 4, 2, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 0, 1, 3, 4, 2, 5 }, result));
+
+		result = CollectionTools.move(array, 0, 5, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 1, 3, 4, 2 }, result));
+
+		result = CollectionTools.move(array, 2, 4, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 4, 1, 3, 2 }, result));
+
+		result = CollectionTools.move(array, 2, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
+
+		result = CollectionTools.move(array, 0, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 0, 3, 2, 4, 5, 1 }, result));
+
+		result = CollectionTools.move(array, 1, 0, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new int[] { 5, 0, 3, 2, 4, 1 }, result));
+	}
+
+	public void testMoveCharArrayIntInt() {
+		char[] array = new char[] { 'a', 'b', 'c', 'd', 'e', 'f' };
+
+		char[] result = CollectionTools.move(array, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'd', 'e', 'c', 'f' }, result));
+
+		result = CollectionTools.move(array, 0, 5);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'b', 'd', 'e', 'c' }, result));
+
+		result = CollectionTools.move(array, 2, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'f', 'a', 'e', 'b', 'd', 'c' }, result));
+	}
+
+	public void testMoveCharArrayIntIntInt() {
+		char[] array = new char[] { 'a', 'b', 'b', 'c', 'd', 'e' };
+
+		char[] result = CollectionTools.move(array, 4, 2, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'a', 'b', 'c', 'd', 'b', 'e' }, result));
+
+		result = CollectionTools.move(array, 0, 5, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'b', 'c', 'd', 'b' }, result));
+
+		result = CollectionTools.move(array, 2, 4, 1);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'd', 'b', 'c', 'b' }, result));
+
+		result = CollectionTools.move(array, 2, 4, 2);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
+
+		result = CollectionTools.move(array, 0, 1, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'a', 'c', 'b', 'd', 'e', 'b' }, result));
+
+		result = CollectionTools.move(array, 1, 0, 4);
+		assertSame(array, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new char[] { 'e', 'a', 'c', 'b', 'd', 'b' }, result));
+	}
+
+	public void testMoveListIntInt() {
+		List<String> list = new ArrayList<String>();
+		CollectionTools.addAll(list, new String[] { "0", "1", "2", "3", "4", "5" });
+
+		List<String> result = CollectionTools.move(list, 4, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
+
+		result = CollectionTools.move(list, 0, 5);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
+
+		result = CollectionTools.move(list, 2, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+	}
+
+	public void testMoveListIntIntInt() {
+		List<String> list = new ArrayList<String>(Arrays.asList(new String[] { "0", "1", "2", "3", "4", "5" }));
+
+		List<String> result = CollectionTools.move(list, 4, 2, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "1", "3", "4", "2", "5" }, result.toArray()));
+
+		result = CollectionTools.move(list, 0, 5, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "1", "3", "4", "2" }, result.toArray()));
+
+		result = CollectionTools.move(list, 2, 4, 1);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "4", "1", "3", "2" }, result.toArray()));
+
+		result = CollectionTools.move(list, 2, 4, 2);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+
+		result = CollectionTools.move(list, 0, 1, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "0", "3", "2", "4", "5", "1" }, result.toArray()));
+
+		result = CollectionTools.move(list, 1, 0, 4);
+		assertSame(list, result);  // the array is modified in place and returned
+		assertTrue(Arrays.equals(new String[] { "5", "0", "3", "2", "4", "1" }, result.toArray()));
+	}
+
 	public void testRemoveAllObjectArrayObjectArray() {
 		String[] a1 = new String[] { "A", "A", "B", "B", "C", "C", "D", "D", "E", "E", "F", "F" };
 		String[] a2 = new String[] { "E", "B" };
@@ -1318,6 +1607,22 @@
 		assertTrue(CollectionTools.contains(a, 50));
 	}
 
+	public void testRemoveAllCollectionIterable() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = this.buildStringList1();
+		assertTrue(CollectionTools.removeAll(c, iterable));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+
+		c = this.buildStringList1();
+		iterable = this.buildStringList2();
+		assertFalse(CollectionTools.removeAll(c, iterable));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+	}
+
 	public void testRemoveAllCollectionIterator1() {
 		Collection<String> c = this.buildStringList1();
 		assertTrue(CollectionTools.removeAll(c, this.buildStringList1().iterator()));
@@ -1341,14 +1646,16 @@
 		c.add("d");
 		c.add("d");
 		String[] a = new String[] { "a", "d" };
-		assertTrue(CollectionTools.removeAll(c, new ArrayIterator<String>(a)));
+		Iterator<String> iterator = new ArrayIterator<String>(a);
+		assertTrue(CollectionTools.removeAll(c, iterator));
 		assertEquals(2, c.size());
 		assertFalse(c.contains("a"));
 		assertTrue(c.contains("b"));
 		assertTrue(c.contains("c"));
 		assertFalse(c.contains("d"));
 
-		assertFalse(CollectionTools.removeAll(c, new ArrayIterator<String>(a)));
+		iterator = new ArrayIterator<String>(a);
+		assertFalse(CollectionTools.removeAll(c, iterator));
 	}
 
 	public void testRemoveAllCollectionIterator3() {
@@ -1360,14 +1667,16 @@
 		c.add("d");
 		c.add("d");
 		String[] a = new String[] { "a", "d" };
-		assertTrue(CollectionTools.removeAll(c, new ArrayIterator<String>(a)));
+		Iterator<String> iterator = new ArrayIterator<String>(a);
+		assertTrue(CollectionTools.removeAll(c, iterator));
 		assertEquals(2, c.size());
 		assertFalse(c.contains("a"));
 		assertTrue(c.contains("b"));
 		assertTrue(c.contains("c"));
 		assertFalse(c.contains("d"));
 
-		assertFalse(CollectionTools.removeAll(c, new ArrayIterator<String>(a)));
+		iterator = new ArrayIterator<String>(a);
+		assertFalse(CollectionTools.removeAll(c, iterator));
 	}
 
 	public void testRemoveAllCollectionObjectArray1() {
@@ -1533,6 +1842,41 @@
 
 	public void testRemoveElementAtIndexIntArrayInt() {
 		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
+		a = CollectionTools.removeElementsAtIndex(a, 3, 3);
+		assertTrue(Arrays.equals(new int[] { 8, 6, 7 }, a));
+	}
+
+	public void testRemoveElementsAtIndexListIntInt() {
+		List<String> list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "A", "C", "A", "D" }));
+		List<String> removed = CollectionTools.removeElementsAtIndex(list, 3, 2);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "D" }, list.toArray()));
+		assertTrue(Arrays.equals(new String[] { "C", "A" }, removed.toArray()));
+
+		list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" }));
+		removed = CollectionTools.removeElementsAtIndex(list, 3, 3);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "C" }, list.toArray()));
+		assertTrue(Arrays.equals(new String[] { "D", "E", "F" }, removed.toArray()));
+
+		list = new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F" }));
+		removed = CollectionTools.removeElementsAtIndex(list, 0, 3);
+		assertTrue(Arrays.equals(new String[] { "D", "E", "F" }, list.toArray()));
+		assertTrue(Arrays.equals(new String[] { "A", "B", "C" }, removed.toArray()));
+	}
+
+	public void testRemoveElementsAtIndexObjectArrayIntInt() {
+		String[] a = new String[] { "A", "B", "A", "C", "A", "D" };
+		a = CollectionTools.removeElementsAtIndex(a, 3, 2);
+		assertTrue(Arrays.equals(new String[] { "A", "B", "A", "D" }, a));
+	}
+
+	public void testRemoveElementsAtIndexCharArrayIntInt() {
+		char[] a = new char[] { 'A', 'B', 'A', 'C', 'A', 'D' };
+		a = CollectionTools.removeElementsAtIndex(a, 0, 5);
+		assertTrue(Arrays.equals(new char[] { 'D' }, a));
+	}
+
+	public void testRemoveElementsAtIndexIntArrayIntInt() {
+		int[] a = new int[] { 8, 6, 7, 33, 2, 11 };
 		a = CollectionTools.removeElementAtIndex(a, 3);
 		assertTrue(Arrays.equals(new int[] { 8, 6, 7, 2, 11 }, a));
 	}
@@ -1561,6 +1905,21 @@
 		assertTrue(Arrays.equals(new int[] { 13, 1, 13, 7, 13, 99 }, a));
 	}
 
+	public void testRetainAllCollectionIterable() {
+		Collection<String> c = this.buildStringList1();
+		Iterable<String> iterable = this.buildStringList1();
+		assertFalse(CollectionTools.retainAll(c, iterable));
+		assertEquals(this.buildStringList1().size(), c.size());
+		assertEquals(this.buildStringList1(), c);
+
+		iterable = this.buildStringList2();
+		assertTrue(CollectionTools.retainAll(c, iterable));
+		assertEquals(0, c.size());
+		assertFalse(c.contains("one"));
+		assertFalse(c.contains("two"));
+		assertFalse(c.contains("three"));
+	}
+
 	public void testRetainAllCollectionIterator1() {
 		Collection<String> c = this.buildStringList1();
 		assertFalse(CollectionTools.retainAll(c, this.buildStringList1().iterator()));
@@ -1664,6 +2023,14 @@
 		assertEquals(0, a[2]);
 	}
 
+	public void testReverseListIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		List<String> actual = CollectionTools.reverseList(iterable);
+		List<String> expected = this.buildStringList1();
+		Collections.reverse(expected);
+		assertEquals(expected, actual);
+	}
+
 	public void testReverseListIterator1() {
 		List<String> actual = CollectionTools.reverseList(this.buildStringList1().iterator());
 		List<String> expected = this.buildStringList1();
@@ -1726,6 +2093,11 @@
 		assertEquals(0, a[2]);
 	}
 
+	public void testSetIterable() {
+		Iterable<String> iterable = this.buildStringSet1();
+		assertEquals(this.buildStringSet1(), CollectionTools.set(iterable));
+	}
+
 	public void testSetIterator1() {
 		assertEquals(this.buildStringSet1(), CollectionTools.set(this.buildStringSet1().iterator()));
 	}
@@ -1784,12 +2156,29 @@
 		assertEquals("foo", stream.next());
 	}
 
+	public void testSizeIterable() {
+		Iterable<Object> iterable = this.buildObjectList1();
+		assertEquals(3, CollectionTools.size(iterable));
+	}
+
 	public void testSizeIterator() {
 		assertEquals(3, CollectionTools.size(this.buildObjectList1().iterator()));
 	}
 
+	public void testSortedSetIterable() {
+		SortedSet<String> ss1 = new TreeSet<String>();
+		ss1.add("0");
+		ss1.add("2");
+		ss1.add("3");
+		ss1.add("1");
+
+		Iterable<String> iterable = ss1;
+		SortedSet<String> set2 = CollectionTools.<String>sortedSet(iterable);
+		assertEquals(ss1, set2);
+	}
+
 	public void testSortedSetIterator1() {
-		assertEquals(this.buildSortedStringSet1(), CollectionTools.set(this.buildSortedStringSet1().iterator()));
+		assertEquals(this.buildSortedStringSet1(), CollectionTools.sortedSet(this.buildSortedStringSet1().iterator()));
 	}
 
 	public void testSortedSetIterator2() {
@@ -1807,6 +2196,51 @@
 		assertEquals(this.buildSortedStringSet1(), CollectionTools.set(this.buildSortedStringSet1().toArray()));
 	}
 
+	public void testSubArrayObjectArrayIntInt() {
+		String[] array = new String[] {"foo", "bar", "baz", "joo", "jar", "jaz"};
+		String[] result = new String[] {"foo", "bar", "baz", "joo"};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 0, 4)));
+
+		result = new String[] {"jar"};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 4, 1)));
+
+		result = new String[0];
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 5, 0)));
+
+		result = new String[] {"joo", "jar", "jaz"};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 3, 3)));
+	}
+
+	public void testSubArrayIntArrayIntInt() {
+		int[] array = new int[] {77, 99, 333, 4, 9090, 42};
+		int[] result = new int[] {77, 99, 333, 4};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 0, 4)));
+
+		result = new int[] {9090};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 4, 1)));
+
+		result = new int[0];
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 5, 0)));
+
+		result = new int[] {4, 9090, 42};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 3, 3)));
+	}
+
+	public void testSubArrayCharArrayIntInt() {
+		char[] array = new char[] {'a', 'b', 'c', 'd', 'e', 'f'};
+		char[] result = new char[] {'a', 'b', 'c', 'd'};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 0, 4)));
+
+		result = new char[] {'e'};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 4, 1)));
+
+		result = new char[0];
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 5, 0)));
+
+		result = new char[] {'d', 'e', 'f'};
+		assertTrue(Arrays.equals(result, CollectionTools.subArray(array, 3, 3)));
+	}
+
 	public void testSwapObjectArray() {
 		String[] a = this.buildStringArray1();
 		a = CollectionTools.swap(a, 1, 2);
@@ -1873,6 +2307,13 @@
 		assertEquals(i, array.length);
 	}
 
+	public void testVectorIterable() {
+		Iterable<String> iterable = this.buildStringList1();
+		Vector<String> v = CollectionTools.vector(iterable);
+		assertEquals(3, v.size());
+		assertTrue(v.containsAll(this.buildStringList1()));
+	}
+
 	public void testVectorIterator1() {
 		Vector<String> v = CollectionTools.vector(this.buildStringList1().iterator());
 		assertEquals(3, v.size());
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/HashBagTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/HashBagTests.java
index 51120c9..30c0c99 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/HashBagTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/HashBagTests.java
@@ -14,11 +14,13 @@
 import java.util.ConcurrentModificationException;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
-import junit.framework.TestCase;
+
 import org.eclipse.jpt.utility.internal.Bag;
 import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.HashBag;
 
+import junit.framework.TestCase;
+
 public class HashBagTests extends TestCase {
 	private HashBag<String> bag;
 
@@ -68,7 +70,7 @@
 		Collection<String> c = this.buildCollection();
 		Bag<String> b = new HashBag<String>(c);
 		for (String s : c) {
-			assertTrue("missing element", b.contains(s));
+			assertTrue(b.contains(s));
 		}
 	}
 
@@ -81,7 +83,7 @@
 		} catch (IllegalArgumentException ex) {
 			exCaught = true;
 		}
-		assertTrue("IllegalArgumentException not thrown", exCaught);
+		assertTrue(exCaught);
 
 		exCaught = false;
 		try {
@@ -89,60 +91,78 @@
 		} catch (IllegalArgumentException ex) {
 			exCaught = true;
 		}
-		assertTrue("IllegalArgumentException not thrown", exCaught);
+		assertTrue(exCaught);
 	}
 
 	public void testAdd() {
 		// the other adds took place in setUp
-		assertTrue("incorrect return value", this.bag.add("five"));
+		assertTrue(this.bag.add("five"));
 
-		assertTrue("missing element", this.bag.contains("one"));
-		assertTrue("missing element", this.bag.contains("two"));
-		assertTrue("missing element", this.bag.contains("three"));
-		assertTrue("missing element", this.bag.contains("four"));
-		assertTrue("missing element", this.bag.contains("five"));
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("two"));
+		assertTrue(this.bag.contains("three"));
+		assertTrue(this.bag.contains("four"));
+		assertTrue(this.bag.contains("five"));
+	}
+
+	public void testAddCount() {
+		// the other adds took place in setUp
+		this.bag.add("minus3", -3);
+		this.bag.add("zero", 0);
+		this.bag.add("five", 5);
+
+		assertFalse(this.bag.contains("minus3"));
+		assertFalse(this.bag.contains("zero"));
+		assertEquals(1, this.bag.count("one"));
+		assertEquals(2, this.bag.count("two"));
+		assertEquals(3, this.bag.count("three"));
+		assertEquals(4, this.bag.count("four"));
+		assertEquals(5, this.bag.count("five"));
+
+		this.bag.add("three", 2);
+		assertEquals(5, this.bag.count("three"));
 	}
 
 	public void testAddAll() {
 		Collection<String> c = this.buildCollection();
-		assertTrue("incorrect return value", this.bag.addAll(c));
+		assertTrue(this.bag.addAll(c));
 		for (String s : c) {
-			assertTrue("missing element", this.bag.contains(s));
+			assertTrue(this.bag.contains(s));
 		}
 	}
 
 	public void testClear() {
-		assertTrue("missing element", this.bag.contains("one"));
-		assertTrue("missing element", this.bag.contains("two"));
-		assertTrue("missing element", this.bag.contains("three"));
-		assertTrue("missing element", this.bag.contains("four"));
-		assertTrue("missing element", this.bag.contains(null));
-		assertEquals("invalid size", 11, this.bag.size());
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("two"));
+		assertTrue(this.bag.contains("three"));
+		assertTrue(this.bag.contains("four"));
+		assertTrue(this.bag.contains(null));
+		assertEquals(11, this.bag.size());
 		this.bag.clear();
-		assertFalse("malingering element", this.bag.contains("one"));
-		assertFalse("malingering element", this.bag.contains("two"));
-		assertFalse("malingering element", this.bag.contains("three"));
-		assertFalse("malingering element", this.bag.contains("four"));
-		assertFalse("malingering element", this.bag.contains(null));
-		assertEquals("invalid size", 0, this.bag.size());
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.contains("three"));
+		assertFalse(this.bag.contains("four"));
+		assertFalse(this.bag.contains(null));
+		assertEquals(0, this.bag.size());
 	}
 
 	public void testClone() {
 		Bag<String> bag2 = this.bag.clone();
-		assertTrue("bad clone", this.bag != bag2);
-		assertEquals("bad clone", this.bag, bag2);
-		assertTrue("bad clone", this.bag.hashCode() == bag2.hashCode());
+		assertTrue(this.bag != bag2);
+		assertEquals(this.bag, bag2);
+		assertTrue(this.bag.hashCode() == bag2.hashCode());
 	}
 
 	public void testContains() {
-		assertTrue("missing element", this.bag.contains(null));
-		assertTrue("missing element", this.bag.contains("one"));
-		assertTrue("missing element", this.bag.contains("two"));
-		assertTrue("missing element", this.bag.contains("three"));
-		assertTrue("missing element", this.bag.contains("four"));
-		assertTrue("missing element", this.bag.contains(new String("four")));
-		assertTrue("missing element", this.bag.contains("fo" + "ur"));
-		assertFalse("element found", this.bag.contains("five"));
+		assertTrue(this.bag.contains(null));
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("two"));
+		assertTrue(this.bag.contains("three"));
+		assertTrue(this.bag.contains("four"));
+		assertTrue(this.bag.contains(new String("four")));
+		assertTrue(this.bag.contains("fo" + "ur"));
+		assertFalse(this.bag.contains("five"));
 	}
 
 	public void testContainsAll() {
@@ -152,53 +172,54 @@
 		c.add(new String("two"));
 		c.add(new String("three"));
 		c.add(new String("four"));
-		assertTrue("missing element(s)", this.bag.containsAll(c));
+		assertTrue(this.bag.containsAll(c));
 	}
 
 	public void testCount() {
-		assertEquals("bad count", 0, this.bag.count("zero"));
-		assertEquals("bad count", 1, this.bag.count("one"));
-		assertEquals("bad count", 2, this.bag.count("two"));
-		assertEquals("bad count", 3, this.bag.count("three"));
-		assertEquals("bad count", 4, this.bag.count("four"));
-		assertEquals("bad count", 0, this.bag.count("five"));
+		assertEquals(0, this.bag.count("zero"));
+		assertEquals(1, this.bag.count("one"));
+		assertEquals(2, this.bag.count("two"));
+		assertEquals(3, this.bag.count("three"));
+		assertEquals(4, this.bag.count("four"));
+		assertEquals(0, this.bag.count("five"));
 	}
 
 	public void testEquals() {
 		Bag<String> bag2 = this.buildBag();
-		assertEquals("bags are not equal", this.bag, bag2);
+		assertEquals(this.bag, bag2);
 		bag2.add("five");
-		assertFalse("bags are equal", this.bag.equals(bag2));
+		assertFalse(this.bag.equals(bag2));
 		Collection<String> c = new ArrayList<String>(this.bag);
-		assertFalse("bags are not equal to collections", this.bag.equals(c));
+		assertFalse(this.bag.equals(c));
 	}
 
 	public void testHashCode() {
 		Bag<String> bag2 = this.buildBag();
-		assertEquals("bad hash code", this.bag.hashCode(), bag2.hashCode());
+		assertEquals(this.bag.hashCode(), bag2.hashCode());
 	}
 
 	public void testIsEmpty() {
-		assertFalse("bag is empty", this.bag.isEmpty());
+		assertFalse(this.bag.isEmpty());
 		this.bag.clear();
-		assertTrue("bag is not empty", this.bag.isEmpty());
+		assertTrue(this.bag.isEmpty());
 		this.bag.add("foo");
-		assertFalse("bag is empty", this.bag.isEmpty());
+		assertFalse(this.bag.isEmpty());
 	}
 
 	public void testEmptyIterator() {
 		this.bag.clear();
 		Iterator<String> iterator = this.bag.iterator();
-		assertFalse("iterator is not empty", iterator.hasNext());
+		assertFalse(iterator.hasNext());
 
 		boolean exCaught = false;
 		Object element = null;
 		try {
 			element = iterator.next();
+			fail(element.toString());
 		} catch (NoSuchElementException ex) {
 			exCaught = true;
 		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+		assertTrue(exCaught);
 
 		exCaught = false;
 		try {
@@ -206,31 +227,32 @@
 		} catch (IllegalStateException ex) {
 			exCaught = true;
 		}
-		assertTrue("IllegalStateException not thrown", exCaught);
+		assertTrue(exCaught);
 	}
 
 	public void testIterator() {
 		int i = 0;
 		Iterator<String> iterator = this.bag.iterator();
-		assertTrue("iterator is empty", iterator.hasNext());
+		assertTrue(iterator.hasNext());
 		while (iterator.hasNext()) {
 			iterator.next();
 			i++;
 		}
-		assertEquals("invalid hasNext() loop", 11, i);
-		assertFalse("iterator should be empty now", iterator.hasNext());
+		assertEquals(11, i);
+		assertFalse(iterator.hasNext());
 
 		boolean exCaught = false;
 		Object element = null;
 		try {
 			element = iterator.next();
+			fail(element.toString());
 		} catch (NoSuchElementException ex) {
 			exCaught = true;
 		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+		assertTrue(exCaught);
 
 		iterator.remove();
-		assertEquals("iterator did not remove element", 10, this.bag.size());
+		assertEquals(10, this.bag.size());
 
 		exCaught = false;
 		try {
@@ -238,7 +260,7 @@
 		} catch (IllegalStateException ex) {
 			exCaught = true;
 		}
-		assertTrue("IllegalStateException not thrown", exCaught);
+		assertTrue(exCaught);
 
 		// start over
 		iterator = this.bag.iterator();
@@ -249,28 +271,29 @@
 		} catch (ConcurrentModificationException ex) {
 			exCaught = true;
 		}
-		assertTrue("ConcurrentModificationException not thrown", exCaught);
+		assertTrue(exCaught);
 	}
 
 	public void testUniqueIterator() {
 		int i = 0;
 		Iterator<String> iterator = this.bag.uniqueIterator();
-		assertTrue("iterator is empty", iterator.hasNext());
+		assertTrue(iterator.hasNext());
 		while (iterator.hasNext()) {
 			iterator.next();
 			i++;
 		}
-		assertEquals("invalid hasNext() loop", 5, i);
-		assertFalse("iterator should be empty now", iterator.hasNext());
+		assertEquals(5, i);
+		assertFalse(iterator.hasNext());
 
 		boolean exCaught = false;
 		Object element = null;
 		try {
 			element = iterator.next();
+			fail(element.toString());
 		} catch (NoSuchElementException ex) {
 			exCaught = true;
 		}
-		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+		assertTrue(exCaught);
 
 		// start over
 		iterator = this.bag.uniqueIterator();
@@ -279,7 +302,7 @@
 			next = iterator.next();
 		}
 		iterator.remove();
-		assertEquals("iterator did not remove all copies of element", 7, this.bag.size());
+		assertEquals(7, this.bag.size());
 
 		exCaught = false;
 		try {
@@ -287,7 +310,7 @@
 		} catch (IllegalStateException ex) {
 			exCaught = true;
 		}
-		assertTrue("IllegalStateException not thrown", exCaught);
+		assertTrue(exCaught);
 
 		// start over
 		iterator = this.bag.uniqueIterator();
@@ -298,7 +321,7 @@
 		} catch (ConcurrentModificationException ex) {
 			exCaught = true;
 		}
-		assertTrue("ConcurrentModificationException not thrown", exCaught);
+		assertTrue(exCaught);
 	}
 
 	public void testHashingDistribution() throws Exception {
@@ -323,64 +346,85 @@
 	}
 
 	public void testRemove() {
-		assertTrue("incorrect return value", this.bag.remove("one"));
-		assertFalse("element still present", this.bag.contains("one"));
-		assertFalse("incorrect return value", this.bag.remove("one"));
+		assertTrue(this.bag.remove("one"));
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.remove("one"));
 
-		assertTrue("incorrect return value", this.bag.remove("two"));
-		assertTrue("incorrect return value", this.bag.remove("two"));
-		assertFalse("element still present", this.bag.contains("one"));
-		assertFalse("incorrect return value", this.bag.remove("one"));
+		assertTrue(this.bag.remove("two"));
+		assertTrue(this.bag.remove("two"));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.remove("two"));
+	}
+
+	public void testRemoveCount() {
+		assertFalse(this.bag.remove("one", 0));
+		assertTrue(this.bag.contains("one"));
+
+		assertTrue(this.bag.remove("one", 1));
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.remove("one"));
+
+		assertFalse(this.bag.remove("two", -3));
+		assertTrue(this.bag.remove("two", 1));
+		assertTrue(this.bag.contains("two"));
+
+		assertTrue(this.bag.remove("two", 1));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.remove("two"));
+
+		assertTrue(this.bag.remove("three", 3));
+		assertFalse(this.bag.contains("three"));
+		assertFalse(this.bag.remove("three"));
 	}
 
 	public void testRemoveAll() {
 		Collection<String> c = new ArrayList<String>();
 		c.add("one");
 		c.add("three");
-		assertTrue("incorrect return value", this.bag.removeAll(c));
-		assertFalse("element still present", this.bag.contains("one"));
-		assertFalse("element still present", this.bag.contains("three"));
-		assertFalse("incorrect return value", this.bag.remove("one"));
-		assertFalse("incorrect return value", this.bag.remove("three"));
-		assertFalse("incorrect return value", this.bag.removeAll(c));
+		assertTrue(this.bag.removeAll(c));
+		assertFalse(this.bag.contains("one"));
+		assertFalse(this.bag.contains("three"));
+		assertFalse(this.bag.remove("one"));
+		assertFalse(this.bag.remove("three"));
+		assertFalse(this.bag.removeAll(c));
 	}
 
 	public void testRetainAll() {
 		Collection<String> c = new ArrayList<String>();
 		c.add("one");
 		c.add("three");
-		assertTrue("incorrect return value", this.bag.retainAll(c));
-		assertTrue("element removed", this.bag.contains("one"));
-		assertTrue("element removed", this.bag.contains("three"));
-		assertFalse("element still present", this.bag.contains("two"));
-		assertFalse("element still present", this.bag.contains("four"));
-		assertFalse("incorrect return value", this.bag.remove("two"));
-		assertFalse("incorrect return value", this.bag.remove("four"));
-		assertFalse("incorrect return value", this.bag.retainAll(c));
+		assertTrue(this.bag.retainAll(c));
+		assertTrue(this.bag.contains("one"));
+		assertTrue(this.bag.contains("three"));
+		assertFalse(this.bag.contains("two"));
+		assertFalse(this.bag.contains("four"));
+		assertFalse(this.bag.remove("two"));
+		assertFalse(this.bag.remove("four"));
+		assertFalse(this.bag.retainAll(c));
 	}
 
 	public void testSize() {
-		assertTrue("incorrect size", this.bag.size() == 11);
+		assertTrue(this.bag.size() == 11);
 		this.bag.add("five");
 		this.bag.add("five");
 		this.bag.add("five");
 		this.bag.add("five");
 		this.bag.add("five");
-		assertEquals("incorrect size", 16, this.bag.size());
+		assertEquals(16, this.bag.size());
 	}
 
 	public void testSerialization() throws Exception {
 		Bag<String> bag2 = TestTools.serialize(this.bag);
 
 		assertTrue("same object?", this.bag != bag2);
-		assertEquals("incorrect size", 11, bag2.size());
-		assertEquals("unequal bag", this.bag, bag2);
+		assertEquals(11, bag2.size());
+		assertEquals(this.bag, bag2);
 		// look for similar elements
-		assertTrue("missing element", bag2.contains(null));
-		assertTrue("missing element", bag2.contains("one"));
-		assertTrue("missing element", bag2.contains("two"));
-		assertTrue("missing element", bag2.contains("three"));
-		assertTrue("missing element", bag2.contains("four"));
+		assertTrue(bag2.contains(null));
+		assertTrue(bag2.contains("one"));
+		assertTrue(bag2.contains("two"));
+		assertTrue(bag2.contains("three"));
+		assertTrue(bag2.contains("four"));
 
 		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
 		for (String s : bag2) {
@@ -396,53 +440,53 @@
 				fourCount++;
 			}
 		}
-		assertEquals("bad element count", 1, nullCount);
-		assertEquals("bad element count", 1, oneCount);
-		assertEquals("bad element count", 2, twoCount);
-		assertEquals("bad element count", 3, threeCount);
-		assertEquals("bad element count", 4, fourCount);
+		assertEquals(1, nullCount);
+		assertEquals(1, oneCount);
+		assertEquals(2, twoCount);
+		assertEquals(3, threeCount);
+		assertEquals(4, fourCount);
 	}
 
 	public void testToArray() {
 		Object[] a = this.bag.toArray();
-		assertEquals("incorrect length", 11, a.length);
-		assertTrue("missing element", CollectionTools.contains(a, null));
-		assertTrue("missing element", CollectionTools.contains(a, "one"));
-		assertTrue("missing element", CollectionTools.contains(a, "two"));
-		assertTrue("missing element", CollectionTools.contains(a, "three"));
-		assertTrue("missing element", CollectionTools.contains(a, "four"));
+		assertEquals(11, a.length);
+		assertTrue(CollectionTools.contains(a, null));
+		assertTrue(CollectionTools.contains(a, "one"));
+		assertTrue(CollectionTools.contains(a, "two"));
+		assertTrue(CollectionTools.contains(a, "three"));
+		assertTrue(CollectionTools.contains(a, "four"));
 	}
 
 	public void testToArrayObjectArray() {
 		String[] a = new String[12];
 		a[11] = "not null";
 		String[] b = this.bag.toArray(a);
-		assertEquals("different array", a, b);
-		assertEquals("incorrect length", 12, a.length);
-		assertTrue("missing element", CollectionTools.contains(a, null));
-		assertTrue("missing element", CollectionTools.contains(a, "one"));
-		assertTrue("missing element", CollectionTools.contains(a, "two"));
-		assertTrue("missing element", CollectionTools.contains(a, "three"));
-		assertTrue("missing element", CollectionTools.contains(a, "four"));
-		assertTrue("missing null element", a[11] == null);
+		assertEquals(a, b);
+		assertEquals(12, a.length);
+		assertTrue(CollectionTools.contains(a, null));
+		assertTrue(CollectionTools.contains(a, "one"));
+		assertTrue(CollectionTools.contains(a, "two"));
+		assertTrue(CollectionTools.contains(a, "three"));
+		assertTrue(CollectionTools.contains(a, "four"));
+		assertTrue(a[11] == null);
 	}
 
 	public void testToString() {
 		String s = this.bag.toString();
-		assertTrue("invalid string prefix", s.startsWith("["));
-		assertTrue("invalid string suffix", s.endsWith("]"));
+		assertTrue(s.startsWith("["));
+		assertTrue(s.endsWith("]"));
 		int commaCount = 0;
 		for (int i = 0; i < s.length(); i++) {
 			if (s.charAt(i) == ',') {
 				commaCount++;
 			}
 		}
-		assertEquals("invalid number of commas", 10, commaCount);
-		assertTrue("missing element toString()", s.indexOf("one") != -1);
-		assertTrue("missing element toString()", s.indexOf("two") != -1);
-		assertTrue("missing element toString()", s.indexOf("three") != -1);
-		assertTrue("missing element toString()", s.indexOf("four") != -1);
-		assertTrue("missing element toString()", s.indexOf("null") != -1);
+		assertEquals(10, commaCount);
+		assertTrue(s.indexOf("one") != -1);
+		assertTrue(s.indexOf("two") != -1);
+		assertTrue(s.indexOf("three") != -1);
+		assertTrue(s.indexOf("four") != -1);
+		assertTrue(s.indexOf("null") != -1);
 	}
 
 }
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/IdentityHashBagTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/IdentityHashBagTests.java
new file mode 100644
index 0000000..8e8ac86
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/IdentityHashBagTests.java
@@ -0,0 +1,509 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.IdentityHashBag;
+
+import junit.framework.TestCase;
+
+public class IdentityHashBagTests extends TestCase {
+	private IdentityHashBag<String> bag;
+	private String one = "one";
+	private String two = "two";
+	private String three = "three";
+	private String four = "four";
+	private String foo = "foo";
+	private String bar = "bar";
+
+	public IdentityHashBagTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.bag = this.buildBag();
+	}
+	
+	protected IdentityHashBag<String> buildBag() {
+		IdentityHashBag<String> result = new IdentityHashBag<String>();
+		result.add(null);
+		result.add(this.one);
+		result.add(this.two);
+		result.add(this.two);
+		result.add(this.three);
+		result.add(this.three);
+		result.add(this.three);
+		result.add(this.four);
+		result.add(this.four);
+		result.add(this.four);
+		result.add(this.four);
+		return result;
+	}
+	
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	private Collection<String> buildCollection() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(this.foo);
+		c.add(this.foo);
+		c.add(this.bar);
+		c.add(this.bar);
+		c.add(this.bar);
+		return c;
+	}
+	
+	public void testCtorCollection() {
+		Collection<String> c = this.buildCollection();
+		IdentityHashBag<String> localBag = new IdentityHashBag<String>(c);
+		for (String s : c) {
+			assertTrue(localBag.contains(s));
+		}
+	}
+	
+	public void testCtorIntFloat() {
+		boolean exCaught;
+	
+		exCaught = false;
+		try {
+			this.bag = new IdentityHashBag<String>(-20, 0.66f);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalArgumentException not thrown", exCaught);
+	
+		exCaught = false;
+		try {
+			this.bag = new IdentityHashBag<String>(20, -0.66f);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalArgumentException not thrown", exCaught);
+	}
+	
+	public void testAdd() {
+		// the other adds took place in setUp
+		String five = "five";
+		assertTrue(this.bag.add(five));
+	
+		assertTrue(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertTrue(this.bag.contains(this.four));
+		assertTrue(this.bag.contains(five));
+	}
+	
+	public void testAddCount() {
+		String minus3 = "minus3";
+		String zero = "zero";
+		String five = "five";
+		// the other adds took place in setUp
+		this.bag.add(minus3, -3);
+		this.bag.add(zero, 0);
+		this.bag.add(five, 5);
+
+		assertFalse(this.bag.contains(minus3));
+		assertFalse(this.bag.contains(zero));
+		assertEquals(1, this.bag.count(this.one));
+		assertEquals(2, this.bag.count(this.two));
+		assertEquals(3, this.bag.count(this.three));
+		assertEquals(4, this.bag.count(this.four));
+		assertEquals(5, this.bag.count(five));
+
+		this.bag.add(this.three, 2);
+		assertEquals(5, this.bag.count(this.three));
+	}
+
+	public void testAddAll() {
+		Collection<String> c = this.buildCollection();
+		assertTrue(this.bag.addAll(c));
+		for (String s : c) {
+			assertTrue(this.bag.contains(s));
+		}
+	}
+	
+	public void testClear() {
+		assertTrue(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertTrue(this.bag.contains(this.four));
+		assertTrue(this.bag.contains(null));
+		assertEquals(11, this.bag.size());
+		this.bag.clear();
+		assertFalse(this.bag.contains(this.one));
+		assertFalse(this.bag.contains(this.two));
+		assertFalse(this.bag.contains(this.three));
+		assertFalse(this.bag.contains(this.four));
+		assertFalse(this.bag.contains(null));
+		assertEquals(0, this.bag.size());
+	}
+	
+	public void testClone() {
+		IdentityHashBag<String> bag2 = this.bag.clone();
+		assertTrue("bad clone", this.bag != bag2);
+		assertEquals("bad clone", this.bag, bag2);
+		assertTrue("bad clone", this.bag.hashCode() == bag2.hashCode());
+	}
+	
+	public void testContains() {
+		assertTrue(this.bag.contains(null));
+		assertTrue(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertTrue(this.bag.contains(this.four));
+
+		assertFalse(this.bag.contains(new String("four")));
+		assertFalse(this.bag.contains("five"));
+	}
+	
+	public void testContainsAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(null);
+		c.add(this.one);
+		c.add(this.two);
+		c.add(this.three);
+		c.add(this.four);
+		assertTrue(this.bag.containsAll(c));
+		c.add(new String(this.four));
+		assertFalse(this.bag.containsAll(c));
+	}
+	
+	public void testCount() {
+		assertEquals(0, this.bag.count("zero"));
+		assertEquals(1, this.bag.count("one"));
+		assertEquals(2, this.bag.count("two"));
+		assertEquals(3, this.bag.count("three"));
+		assertEquals(4, this.bag.count("four"));
+		assertEquals(0, this.bag.count("five"));
+	}
+	
+	public void testEquals() {
+		IdentityHashBag<String> bag2 = this.buildBag();
+		assertEquals(this.bag, bag2);
+		bag2.add("five");
+		assertFalse(this.bag.equals(bag2));
+		Collection<String> c = new ArrayList<String>(this.bag);
+		assertFalse(this.bag.equals(c));
+	}
+	
+	public void testHashCode() {
+		IdentityHashBag<String> bag2 = this.buildBag();
+		assertEquals(this.bag.hashCode(), bag2.hashCode());
+	}
+	
+	public void testIsEmpty() {
+		assertFalse(this.bag.isEmpty());
+		this.bag.clear();
+		assertTrue(this.bag.isEmpty());
+		this.bag.add("foo");
+		assertFalse(this.bag.isEmpty());
+	}
+	
+	public void testEmptyIterator() {
+		this.bag.clear();
+		Iterator<String> iterator = this.bag.iterator();
+		assertFalse(iterator.hasNext());
+	
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+	
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	}
+	
+	public void testIterator() {
+		int i = 0;
+		Iterator<String> iterator = this.bag.iterator();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(11, i);
+		assertFalse(iterator.hasNext());
+	
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue("NoSuchElementException not thrown: " + element, exCaught);
+	
+		iterator.remove();
+		assertEquals(10, this.bag.size());
+	
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue("IllegalStateException not thrown", exCaught);
+	
+		// start over
+		iterator = this.bag.iterator();
+		this.bag.add("five");
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue("ConcurrentModificationException not thrown", exCaught);
+	}
+	
+	public void testUniqueIterator() {
+		int i = 0;
+		Iterator<String> iterator = this.bag.uniqueIterator();
+		assertTrue(iterator.hasNext());
+		while (iterator.hasNext()) {
+			iterator.next();
+			i++;
+		}
+		assertEquals(5, i);
+		assertFalse(iterator.hasNext());
+
+		boolean exCaught = false;
+		Object element = null;
+		try {
+			element = iterator.next();
+			fail(element.toString());
+		} catch (NoSuchElementException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.uniqueIterator();
+		Object next = null;
+		while (iterator.hasNext() && !this.four.equals(next)) {
+			next = iterator.next();
+		}
+		iterator.remove();
+		assertEquals(7, this.bag.size());
+
+		exCaught = false;
+		try {
+			iterator.remove();
+		} catch (IllegalStateException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		// start over
+		iterator = this.bag.uniqueIterator();
+		String five = "five";
+		this.bag.add(five);
+		exCaught = false;
+		try {
+			iterator.next();
+		} catch (ConcurrentModificationException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testHashingDistribution() throws Exception {
+		IdentityHashBag<String> bigBag = new IdentityHashBag<String>();
+		for (int i = 0; i < 10000; i++) {
+			bigBag.add("object" + i);
+		}
+	
+		java.lang.reflect.Field field = bigBag.getClass().getDeclaredField("table");
+		field.setAccessible(true);
+		Object[] table = (Object[]) field.get(bigBag);
+		int bucketCount = table.length;
+		int filledBucketCount = 0;
+		for (int i = 0; i < bucketCount; i++) {
+			if (table[i] != null) {
+				filledBucketCount++;
+			}
+		}
+		float loadFactor = ((float) filledBucketCount)/((float) bucketCount);
+		assertTrue("WARNING - poor load factor: " + loadFactor, loadFactor > 0.20);
+		assertTrue("WARNING - poor load factor: " + loadFactor, loadFactor < 0.75);
+	}
+	
+	public void testRemove() {
+		assertTrue(this.bag.remove(this.one));
+		assertFalse(this.bag.contains(this.one));
+		assertFalse(this.bag.remove(this.one));
+	
+		assertTrue(this.bag.remove(this.two));
+		assertTrue(this.bag.remove(this.two));
+		assertFalse(this.bag.contains(this.two));
+		assertFalse(this.bag.remove(this.two));
+
+		assertFalse(this.bag.remove(new String(this.three)));
+	}
+	
+	public void testRemoveCount() {
+		assertFalse(this.bag.remove(this.one, 0));
+		assertTrue(this.bag.contains(this.one));
+
+		assertTrue(this.bag.remove(this.one, 1));
+		assertFalse(this.bag.contains(this.one));
+		assertFalse(this.bag.remove(this.one));
+
+		assertFalse(this.bag.remove(this.two, -3));
+		assertTrue(this.bag.remove(this.two, 1));
+		assertTrue(this.bag.contains(this.two));
+
+		assertTrue(this.bag.remove(this.two, 1));
+		assertFalse(this.bag.contains(this.two));
+		assertFalse(this.bag.remove(this.two));
+
+		assertTrue(this.bag.remove(this.three, 3));
+		assertFalse(this.bag.contains(this.three));
+		assertFalse(this.bag.remove(this.three));
+	}
+
+	public void testRemoveAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(this.one);
+		c.add(new String(this.two));
+		c.add(this.three);
+		assertTrue(this.bag.removeAll(c));
+		assertFalse(this.bag.contains(this.one));
+		assertTrue(this.bag.contains(this.two));
+		assertFalse(this.bag.contains(this.three));
+		assertFalse(this.bag.remove(this.one));
+		assertTrue(this.bag.remove(this.two));
+		assertFalse(this.bag.remove(this.three));
+		assertFalse(this.bag.removeAll(c));
+	}
+	
+	public void testRetainAll() {
+		Collection<String> c = new ArrayList<String>();
+		c.add(this.one);
+		c.add(new String(this.two));
+		c.add(this.three);
+		assertTrue(this.bag.retainAll(c));
+		assertTrue(this.bag.contains(this.one));
+		assertFalse(this.bag.contains(this.two));
+		assertTrue(this.bag.contains(this.three));
+		assertFalse(this.bag.contains(this.four));
+		assertFalse(this.bag.remove(this.two));
+		assertFalse(this.bag.remove(this.four));
+		assertFalse(this.bag.retainAll(c));
+	}
+	
+	public void testSize() {
+		assertTrue(this.bag.size() == 11);
+		String five = "five";
+		this.bag.add(five);
+		this.bag.add(five);
+		this.bag.add(five);
+		this.bag.add(five);
+		this.bag.add(new String(five));
+		assertEquals(16, this.bag.size());
+	}
+	
+	public void testSerialization() throws Exception {
+		@SuppressWarnings("cast")
+		IdentityHashBag<String> bag2 = (IdentityHashBag<String>) TestTools.serialize(this.bag);
+	
+		assertTrue("same object?", this.bag != bag2);
+		assertEquals(11, bag2.size());
+		assertEquals(CollectionTools.bag(this.bag.iterator()), CollectionTools.bag(bag2.iterator()));
+		// look for similar elements
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains(null));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("one"));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("two"));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("three"));
+		assertTrue(CollectionTools.bag(bag2.iterator()).contains("four"));
+	
+		int nullCount = 0, oneCount = 0, twoCount = 0, threeCount = 0, fourCount = 0;
+		for (String next : bag2) {
+			if (next == null)
+				nullCount++;
+			else if (next.equals("one"))
+				oneCount++;
+			else if (next.equals("two"))
+				twoCount++;
+			else if (next.equals("three"))
+				threeCount++;
+			else if (next.equals("four"))
+				fourCount++;
+		}
+		assertEquals(1, nullCount);
+		assertEquals(1, oneCount);
+		assertEquals(2, twoCount);
+		assertEquals(3, threeCount);
+		assertEquals(4, fourCount);
+	}
+	
+	public void testToArray() {
+		Object[] a = this.bag.toArray();
+		assertEquals(11, a.length);
+		assertTrue(CollectionTools.contains(a, null));
+		assertTrue(CollectionTools.contains(a, this.one));
+		assertTrue(CollectionTools.contains(a, this.two));
+		assertTrue(CollectionTools.contains(a, this.three));
+		assertTrue(CollectionTools.contains(a, this.four));
+	}
+	
+	public void testToArrayObjectArray() {
+		String[] a = new String[12];
+		a[11] = "not null";
+		String[] b = this.bag.toArray(a);
+		assertEquals(a, b);
+		assertEquals(12, a.length);
+		assertTrue(CollectionTools.contains(a, null));
+		assertTrue(CollectionTools.contains(a, this.one));
+		assertTrue(CollectionTools.contains(a, this.two));
+		assertTrue(CollectionTools.contains(a, this.three));
+		assertTrue(CollectionTools.contains(a, this.four));
+		assertTrue(a[11] == null);
+	}
+	
+	public void testToString() {
+		String s = this.bag.toString();
+		assertTrue(s.startsWith("["));
+		assertTrue(s.endsWith("]"));
+		int commaCount = 0;
+		for (int i = 0; i < s.length(); i++) {
+			if (s.charAt(i) == ',') {
+				commaCount++;
+			}
+		}
+		assertEquals("invalid number of commas", 10, commaCount);
+		assertTrue(s.indexOf("one") != -1);
+		assertTrue(s.indexOf("two") != -1);
+		assertTrue(s.indexOf("three") != -1);
+		assertTrue(s.indexOf("four") != -1);
+		assertTrue(s.indexOf("null") != -1);
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
index 82143f3..7d7a7a0 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
@@ -9,10 +9,13 @@
  ******************************************************************************/
 package org.eclipse.jpt.utility.tests.internal;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
 import org.eclipse.jpt.utility.internal.ClassTools;
 import org.eclipse.jpt.utility.tests.internal.iterators.JptUtilityIteratorsTests;
+import org.eclipse.jpt.utility.tests.internal.model.JptUtilityModelTests;
+import org.eclipse.jpt.utility.tests.internal.node.JptUtilityNodeTests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
 
 /**
  * decentralize test creation code
@@ -23,6 +26,8 @@
 		TestSuite suite = new TestSuite(ClassTools.packageNameFor(JptUtilityTests.class));
 
 		suite.addTest(JptUtilityIteratorsTests.suite());
+		suite.addTest(JptUtilityModelTests.suite());
+		suite.addTest(JptUtilityNodeTests.suite());
 
 		suite.addTestSuite(BitToolsTests.class);
 		suite.addTestSuite(ClasspathTests.class);
@@ -30,12 +35,17 @@
 		suite.addTestSuite(CollectionToolsTests.class);
 		suite.addTestSuite(FileToolsTests.class);
 		suite.addTestSuite(HashBagTests.class);
+		suite.addTestSuite(IdentityHashBagTests.class);
 		suite.addTestSuite(IndentingPrintWriterTests.class);
 		suite.addTestSuite(JavaTypeTests.class);
 		suite.addTestSuite(JDBCTypeTests.class);
 		suite.addTestSuite(NameToolsTests.class);
 		suite.addTestSuite(ReverseComparatorTests.class);
+		suite.addTestSuite(SimpleStackTests.class);
 		suite.addTestSuite(StringToolsTests.class);
+		suite.addTestSuite(SynchronizedBooleanTests.class);
+		suite.addTestSuite(SynchronizedObjectTests.class);
+		suite.addTestSuite(SynchronizedStackTests.class);
 		suite.addTestSuite(XMLStringEncoderTests.class);
 
 		return suite;
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java
new file mode 100644
index 0000000..f229797
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SimpleStackTests.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal;
+
+import java.util.EmptyStackException;
+
+import org.eclipse.jpt.utility.internal.SimpleStack;
+import org.eclipse.jpt.utility.internal.Stack;
+
+import junit.framework.TestCase;
+
+public class SimpleStackTests extends TestCase {
+
+	public SimpleStackTests(String name) {
+		super(name);
+	}
+
+	public void testIsEmpty() {
+		Stack<String> stack = new SimpleStack<String>();
+		assertTrue(stack.isEmpty());
+		stack.push("first");
+		assertFalse(stack.isEmpty());
+		stack.push("second");
+		assertFalse(stack.isEmpty());
+		stack.pop();
+		assertFalse(stack.isEmpty());
+		stack.pop();
+		assertTrue(stack.isEmpty());
+	}
+
+	public void testPushAndPop() {
+		Stack<String> stack = new SimpleStack<String>();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.pop());
+	}
+
+	public void testPushAndPeek() {
+		Stack<String> stack = new SimpleStack<String>();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.pop());
+	}
+
+	public void testEmptyStackExceptionPeek() {
+		Stack<String> stack = new SimpleStack<String>();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.pop());
+
+		boolean exCaught = false;
+		try {
+			stack.peek();
+		} catch (EmptyStackException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testEmptyStackExceptionPop() {
+		Stack<String> stack = new SimpleStack<String>();
+		String first = "first";
+		String second = "second";
+
+		stack.push(first);
+		stack.push(second);
+		assertEquals(second, stack.peek());
+		assertEquals(second, stack.pop());
+		assertEquals(first, stack.peek());
+		assertEquals(first, stack.pop());
+
+		boolean exCaught = false;
+		try {
+			stack.pop();
+		} catch (EmptyStackException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testClone() {
+		SimpleStack<String> stack = new SimpleStack<String>();
+		stack.push("first");
+		stack.push("second");
+		stack.push("third");
+
+		this.verifyClone(stack, stack.clone());
+	}
+
+	public void testSerialization() throws Exception {
+		SimpleStack<String> stack = new SimpleStack<String>();
+		stack.push("first");
+		stack.push("second");
+		stack.push("third");
+
+		this.verifyClone(stack, TestTools.serialize(stack));
+	}
+
+	private void verifyClone(Stack<String> original, Stack<String> clone) {
+		assertNotSame(original, clone);
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.pop(), clone.pop());
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.pop(), clone.pop());
+		assertEquals(original.isEmpty(), clone.isEmpty());
+		assertEquals(original.peek(), clone.peek());
+		assertEquals(original.pop(), clone.pop());
+		assertTrue(original.isEmpty());
+		assertEquals(original.isEmpty(), clone.isEmpty());
+
+		original.push("fourth");
+		assertFalse(original.isEmpty());
+		// clone should still be empty
+		assertTrue(clone.isEmpty());
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java
new file mode 100644
index 0000000..4b42839
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedBooleanTests.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal;
+
+import org.eclipse.jpt.utility.internal.SynchronizedBoolean;
+
+import junit.framework.TestCase;
+
+public class SynchronizedBooleanTests extends TestCase {
+	private volatile SynchronizedBoolean sb;
+	private volatile boolean exCaught;
+	private volatile boolean timeoutOccurred;
+	private volatile long startTime;
+	private volatile long endTime;
+
+
+	public SynchronizedBooleanTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.sb = new SynchronizedBoolean();
+		this.exCaught = false;
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testAccessors() throws Exception {
+		this.sb.setValue(false);
+		assertFalse(this.sb.value());
+		assertFalse(this.sb.isTrue());
+		assertTrue(this.sb.isFalse());
+
+		this.sb.setValue(true);
+		assertTrue(this.sb.value());
+		assertTrue(this.sb.isTrue());
+		assertFalse(this.sb.isFalse());
+
+		this.sb.setFalse();
+		assertFalse(this.sb.value());
+		assertFalse(this.sb.isTrue());
+		assertTrue(this.sb.isFalse());
+
+		this.sb.setTrue();
+		assertTrue(this.sb.value());
+		assertTrue(this.sb.isTrue());
+		assertFalse(this.sb.isFalse());
+
+		assertSame(this.sb, this.sb.mutex());
+	}
+
+	public void testEquals() throws Exception {
+		this.sb.setValue(false);
+		SynchronizedBoolean sb2 = new SynchronizedBoolean(false);
+		assertEquals(this.sb, sb2);
+
+		this.sb.setValue(true);
+		assertFalse(this.sb.equals(sb2));
+
+		sb2.setValue(true);
+		assertEquals(this.sb, sb2);
+	}
+
+	public void testHashCode() {
+		this.sb.setValue(false);
+		assertEquals(0, this.sb.hashCode());
+
+		this.sb.setValue(true);
+		assertEquals(1, this.sb.hashCode());
+	}
+
+	public void testWaitUntilTrue() throws Exception {
+		this.verifyWaitUntilTrue(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to true by t2
+		assertTrue(this.sb.value());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() > 150);
+	}
+
+	public void testWaitUntilTrueTimeout() throws Exception {
+		this.verifyWaitUntilTrue(20);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to true by t1
+		assertTrue(this.sb.value());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() < 150);
+	}
+
+	private void verifyWaitUntilTrue(long timeout) throws Exception {
+		this.sb.setFalse();
+		Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200);
+		Runnable r2 = this.buildRunnable(this.buildWaitUntilTrueCommand(timeout), this.sb, 0);
+		Thread t1 = new Thread(r1);
+		Thread t2 = new Thread(r2);
+		t1.start();
+		t2.start();
+		while (t1.isAlive() || t2.isAlive()) {
+			Thread.sleep(50);
+		}
+		assertFalse(this.exCaught);
+	}
+
+	public void testWaitToSetFalse() throws Exception {
+		this.verifyWaitToSetFalse(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to false by t2
+		assertFalse(this.sb.value());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() > 150);
+	}
+
+	public void testWaitToSetFalseTimeout() throws Exception {
+		this.verifyWaitToSetFalse(20);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to true by t1
+		assertTrue(this.sb.value());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() < 150);
+	}
+
+	private void verifyWaitToSetFalse(long timeout) throws Exception {
+		this.sb.setFalse();
+		Runnable r1 = this.buildRunnable(this.buildSetTrueCommand(), this.sb, 200);
+		Runnable r2 = this.buildRunnable(this.buildWaitToSetFalseCommand(timeout), this.sb, 0);
+		Thread t1 = new Thread(r1);
+		Thread t2 = new Thread(r2);
+		t1.start();
+		t2.start();
+		while (t1.isAlive() || t2.isAlive()) {
+			Thread.sleep(50);
+		}
+		assertFalse(this.exCaught);
+	}
+
+	private Command buildSetTrueCommand() {
+		return new Command() {
+			public void execute(SynchronizedBoolean syncBool) {
+				syncBool.setTrue();
+			}
+		};
+	}
+
+	private Command buildWaitUntilTrueCommand(final long timeout) {
+		return new Command() {
+			public void execute(SynchronizedBoolean syncBool) throws Exception {
+				SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis());
+				SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitUntilTrue(timeout));
+				SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Command buildWaitToSetFalseCommand(final long timeout) {
+		return new Command() {
+			public void execute(SynchronizedBoolean syncBool) throws Exception {
+				SynchronizedBooleanTests.this.setStartTime(System.currentTimeMillis());
+				SynchronizedBooleanTests.this.setTimeoutOccurred( ! syncBool.waitToSetFalse(timeout));
+				SynchronizedBooleanTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedBoolean syncBool, final long sleep) {
+		return new Runnable() {
+			public void run() {
+				try {
+					if (sleep != 0) {
+						Thread.sleep(sleep);
+					}
+					command.execute(syncBool);
+				} catch (Exception ex) {
+					SynchronizedBooleanTests.this.setExCaught(true);
+				}
+			}
+		};
+	}
+
+	void setExCaught(boolean exCaught) {
+		this.exCaught = exCaught;
+	}
+
+	void setTimeoutOccurred(boolean timeoutOccurred) {
+		this.timeoutOccurred = timeoutOccurred;
+	}
+
+	void setStartTime(long startTime) {
+		this.startTime = startTime;
+	}
+
+	void setEndTime(long endTime) {
+		this.endTime = endTime;
+	}
+
+	long elapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedBoolean syncBool) throws Exception;
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java
new file mode 100644
index 0000000..1eba5ba
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedObjectTests.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal;
+
+import org.eclipse.jpt.utility.internal.SynchronizedObject;
+
+import junit.framework.TestCase;
+
+public class SynchronizedObjectTests extends TestCase {
+	private volatile SynchronizedObject<Object> so;
+	private volatile boolean exCaught;
+	private volatile boolean timeoutOccurred;
+	volatile Object value = new Object();
+	private volatile long startTime;
+	private volatile long endTime;
+	private volatile Object soValue;
+
+
+	public SynchronizedObjectTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.so = new SynchronizedObject<Object>();
+		this.exCaught = false;
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+		this.soValue = null;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testAccessors() throws Exception {
+		this.so.setValue(null);
+		assertNull(this.so.value());
+		assertFalse(this.so.isNotNull());
+		assertTrue(this.so.isNull());
+
+		this.so.setValue(this.value);
+		assertEquals(this.value, this.so.value());
+		assertTrue(this.so.isNotNull());
+		assertFalse(this.so.isNull());
+
+		this.so.setNull();
+		assertNull(this.so.value());
+		assertFalse(this.so.isNotNull());
+		assertTrue(this.so.isNull());
+
+		assertSame(this.so, this.so.mutex());
+	}
+
+	public void testEquals() throws Exception {
+		this.so.setValue(null);
+		SynchronizedObject<Object> so2 = new SynchronizedObject<Object>(null);
+		assertEquals(this.so, so2);
+
+		this.so.setValue(this.value);
+		assertFalse(this.so.equals(so2));
+
+		so2.setValue(this.value);
+		assertEquals(this.so, so2);
+	}
+
+	public void testHashCode() {
+		this.so.setValue(this.value);
+		assertEquals(this.value.hashCode(), this.so.hashCode());
+
+		this.so.setValue(null);
+		assertEquals(0, this.so.hashCode());
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to null
+	 */
+	public void testWaitUntilNull() throws Exception {
+		this.verifyWaitUntilNull(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to null by t2
+		assertNull(this.so.value());
+		// make a reasonable guess about how long t2 took
+		long time = this.elapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to null
+	 */
+	public void testWaitUntilNullTimeout() throws Exception {
+		this.verifyWaitUntilNull(20);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to null by t1
+		assertNull(this.so.value());
+		// make a reasonable guess about how long t2 took
+		long time = this.elapsedTime();
+		assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
+	}
+
+	private void verifyWaitUntilNull(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetNullCommand(), this.buildWaitUntilNullCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait indefinitely until t1 sets the value to null;
+	 * then t2 will set the value to an object
+	 */
+	public void testWaitToSetValue() throws Exception {
+		this.verifyWaitToSetValue(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the value should be set to an object by t2
+		assertTrue(this.so.isNotNull());
+		// make a reasonable guess about how long t2 took
+		long time = this.elapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > 150): " + time, time > 150);
+	}
+
+	/**
+	 * t2 will time out waiting for t1 to set the value to null
+	 */
+	public void testWaitToSetValueTimeout() throws Exception {
+		this.verifyWaitToSetValue(20);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the value will eventually be set to null by t1
+		assertTrue(this.so.isNull());
+		// make a reasonable guess about how long t2 took
+		long time = this.elapsedTime();
+		assertTrue("t2 finished a bit late (expected value should be < 150): " + time, time < 150);
+	}
+
+	private void verifyWaitToSetValue(long t2Timeout) throws Exception {
+		this.executeThreads(this.buildSetNullCommand(), this.buildWaitToSetValueCommand(t2Timeout));
+	}
+
+	/**
+	 * t2 will wait until t1 is finished "initializing" the value;
+	 * then t2 will get the newly-initialized value ("foo")
+	 */
+	public void testExecute() throws Exception {
+		this.so.setValue(null);
+		Runnable r1 = this.buildRunnable(this.buildInitializeValueCommand(), this.so, 0);
+		// give t1 a head start of 100 ms
+		Runnable r2 = this.buildRunnable(this.buildGetValueCommand(), this.so, 100);
+		Thread t1 = new Thread(r1);
+		Thread t2 = new Thread(r2);
+		t1.start();
+		t2.start();
+		while (t1.isAlive() || t2.isAlive()) {
+			Thread.sleep(50);
+		}
+		assertFalse(this.exCaught);
+		assertEquals("foo", this.so.value());
+		assertEquals("foo", this.soValue);
+		// make a reasonable guess about how long t2 took
+		long time = this.elapsedTime();
+		assertTrue("t2 finished a bit early (expected value should be > 100): " + time, time > 300);
+	}
+
+	private void executeThreads(Command t1Command, Command t2Command) throws Exception {
+		this.so.setValue(this.value);
+		Runnable r1 = this.buildRunnable(t1Command, this.so, 200);
+		Runnable r2 = this.buildRunnable(t2Command, this.so, 0);
+		Thread t1 = new Thread(r1);
+		Thread t2 = new Thread(r2);
+		t1.start();
+		t2.start();
+		while (t1.isAlive() || t2.isAlive()) {
+			Thread.sleep(50);
+		}
+		assertFalse(this.exCaught);
+	}
+
+	private Command buildSetNullCommand() {
+		return new Command() {
+			public void execute(SynchronizedObject<Object> sObject) {
+				sObject.setNull();
+			}
+		};
+	}
+
+	private Command buildWaitUntilNullCommand(final long timeout) {
+		return new Command() {
+			public void execute(SynchronizedObject<Object> sObject) throws Exception {
+				SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
+				SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitUntilNull(timeout));
+				SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Command buildWaitToSetValueCommand(final long timeout) {
+		return new Command() {
+			public void execute(SynchronizedObject<Object> sObject) throws Exception {
+				SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
+				SynchronizedObjectTests.this.setTimeoutOccurred( ! sObject.waitToSetValue(SynchronizedObjectTests.this.value, timeout));
+				SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Command buildInitializeValueCommand() {
+		return new Command() {
+			public void execute(final SynchronizedObject<Object> sObject) throws Exception {
+				sObject.execute(
+					new org.eclipse.jpt.utility.internal.Command() {
+						public void execute() {
+							// pretend to perform some long initialization process
+							try {
+								Thread.sleep(500);
+							} catch (Exception ex) {
+								SynchronizedObjectTests.this.setExCaught(true);
+							}
+							sObject.setValue("foo");
+						}
+					}
+				);
+			}
+		};
+	}
+
+	private Command buildGetValueCommand() {
+		return new Command() {
+			public void execute(SynchronizedObject<Object> sObject) throws Exception {
+				SynchronizedObjectTests.this.setStartTime(System.currentTimeMillis());
+				SynchronizedObjectTests.this.setSOValue(sObject.value());
+				SynchronizedObjectTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedObject<Object> sObject, final long sleep) {
+		return new Runnable() {
+			public void run() {
+				try {
+					if (sleep != 0) {
+						Thread.sleep(sleep);
+					}
+					command.execute(sObject);
+				} catch (Exception ex) {
+					SynchronizedObjectTests.this.setExCaught(true);
+				}
+			}
+		};
+	}
+
+	void setExCaught(boolean exCaught) {
+		this.exCaught = exCaught;
+	}
+
+	void setTimeoutOccurred(boolean timeoutOccurred) {
+		this.timeoutOccurred = timeoutOccurred;
+	}
+
+	void setStartTime(long startTime) {
+		this.startTime = startTime;
+	}
+
+	void setEndTime(long endTime) {
+		this.endTime = endTime;
+	}
+
+	private long elapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+	void setSOValue(Object soValue) {
+		this.soValue = soValue;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedObject<Object> so) throws Exception;
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java
new file mode 100644
index 0000000..adb83d9
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/SynchronizedStackTests.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal;
+
+import java.util.EmptyStackException;
+
+import org.eclipse.jpt.utility.internal.SimpleStack;
+import org.eclipse.jpt.utility.internal.Stack;
+import org.eclipse.jpt.utility.internal.SynchronizedStack;
+
+public class SynchronizedStackTests extends SimpleStackTests {
+	private volatile SynchronizedStack<String> ss;
+	private volatile boolean exCaught;
+	private volatile boolean timeoutOccurred;
+	private volatile long startTime;
+	private volatile long endTime;
+	private volatile Object poppedObject;
+
+	static final String ITEM_1 = new String();
+	static final String ITEM_2 = new String();
+
+	public SynchronizedStackTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.ss = new SynchronizedStack<String>();
+		this.exCaught = false;
+		this.timeoutOccurred = false;
+		this.startTime = 0;
+		this.endTime = 0;
+		this.poppedObject = null;
+	}
+
+	/**
+	 * test first with an unsynchronized stack,
+	 * then with a synchronized stack
+	 */
+	public void testConcurrentAccess() throws Exception {
+		this.verifyConcurrentAccess(new SlowSimpleStack<String>(), "second");
+		this.verifyConcurrentAccess(new SlowSynchronizedStack<String>(), "first");
+	}
+
+	private void verifyConcurrentAccess(SlowStack<String> slowStack, String expected) throws Exception {
+		slowStack.push("first");
+		slowStack.push("second");
+
+		new Thread(this.buildRunnable(slowStack)).start();
+		Thread.sleep(200);
+
+		assertEquals(expected, slowStack.pop());
+	}
+
+	private Runnable buildRunnable(final SlowStack<String> slowStack) {
+		return new Runnable() {
+			public void run() {
+				slowStack.slowPop();
+			}
+		};
+	}
+
+
+	private interface SlowStack<E> extends Stack<E> {
+		Object slowPop();
+	}
+
+	private class SlowSimpleStack<E> extends SimpleStack<E> implements SlowStack<E> {
+		SlowSimpleStack() {
+			super();
+		}
+		public Object slowPop() {
+			try {
+				Thread.sleep(500);
+			} catch (InterruptedException ex) {
+				throw new RuntimeException(ex);
+			}
+			return this.pop();
+		}
+
+	}
+
+	private class SlowSynchronizedStack<E> extends SynchronizedStack<E> implements SlowStack<E> {
+		SlowSynchronizedStack() {
+			super();
+		}
+		public synchronized Object slowPop() {
+			try {
+				Thread.sleep(100);
+			} catch (InterruptedException ex) {
+				throw new RuntimeException(ex);
+			}
+			return this.pop();
+		}
+
+	}
+
+
+	// ********** waits **********
+
+	public void testWaitToPop() throws Exception {
+		this.verifyWaitToPop(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and an item should have been popped by t2...
+		assertSame(ITEM_1, this.poppedObject);
+		// ...and the stack should be empty
+		assertTrue(this.ss.isEmpty());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() > 150);
+	}
+
+	public void testWaitToPopTimeout() throws Exception {
+		this.verifyWaitToPop(20);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the stack was never popped...
+		assertNull(this.poppedObject);
+		// ...and it still holds the item
+		assertSame(ITEM_1, this.ss.peek());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() < 150);
+	}
+
+	private void verifyWaitToPop(long timeout) throws Exception {
+		Runnable r1 = this.buildRunnable(this.buildPushCommand(), this.ss, 200);
+		Runnable r2 = this.buildRunnable(this.buildWaitToPopCommand(timeout), this.ss, 0);
+		Thread t1 = new Thread(r1);
+		Thread t2 = new Thread(r2);
+		t1.start();
+		t2.start();
+		while (t1.isAlive() || t2.isAlive()) {
+			Thread.sleep(50);
+		}
+		assertFalse(this.exCaught);
+	}
+
+	public void testWaitToPush() throws Exception {
+		this.verifyWaitToPush(0);
+		// no timeout occurs...
+		assertFalse(this.timeoutOccurred);
+		// ...and the stack gets popped by t1...
+		assertSame(ITEM_1, this.poppedObject);
+		// ...and an item is pushed on to the stack by t2
+		assertFalse(this.ss.isEmpty());
+		assertSame(ITEM_2, this.ss.peek());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() > 150);
+	}
+
+	public void testWaitToPushTimeout() throws Exception {
+		this.verifyWaitToPush(20);
+		// timeout occurs...
+		assertTrue(this.timeoutOccurred);
+		// ...and the stack is eventually popped by t1...
+		assertSame(ITEM_1, this.poppedObject);
+		// ...but nothing is pushed on to the stack by t2
+		assertTrue(this.ss.isEmpty());
+		// make a reasonable guess about how long t2 took
+		assertTrue(this.elapsedTime() < 150);
+	}
+
+	private void verifyWaitToPush(long timeout) throws Exception {
+		this.ss.push(ITEM_1);
+		Runnable r1 = this.buildRunnable(this.buildPopCommand(), this.ss, 200);
+		Runnable r2 = this.buildRunnable(this.buildWaitToPushCommand(timeout), this.ss, 0);
+		Thread t1 = new Thread(r1);
+		Thread t2 = new Thread(r2);
+		t1.start();
+		t2.start();
+		while (t1.isAlive() || t2.isAlive()) {
+			Thread.sleep(50);
+		}
+		assertFalse(this.exCaught);
+	}
+
+	private Command buildPushCommand() {
+		return new Command() {
+			public void execute(SynchronizedStack<String> synchronizedStack) {
+				synchronizedStack.push(ITEM_1);
+			}
+		};
+	}
+
+	private Command buildWaitToPopCommand(final long timeout) {
+		return new Command() {
+			public void execute(SynchronizedStack<String> synchronizedStack) throws Exception {
+				SynchronizedStackTests.this.setStartTime(System.currentTimeMillis());
+				try {
+					SynchronizedStackTests.this.setPoppedObject(synchronizedStack.waitToPop(timeout));
+				} catch (EmptyStackException ex) {
+					SynchronizedStackTests.this.setTimeoutOccurred(true);
+				}
+				SynchronizedStackTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Command buildPopCommand() {
+		return new Command() {
+			public void execute(SynchronizedStack<String> synchronizedStack) {
+				SynchronizedStackTests.this.setPoppedObject(synchronizedStack.pop());
+			}
+		};
+	}
+
+	private Command buildWaitToPushCommand(final long timeout) {
+		return new Command() {
+			public void execute(SynchronizedStack<String> synchronizedStack) throws Exception {
+				SynchronizedStackTests.this.setStartTime(System.currentTimeMillis());
+				SynchronizedStackTests.this.setTimeoutOccurred( ! synchronizedStack.waitToPush(ITEM_2, timeout));
+				SynchronizedStackTests.this.setEndTime(System.currentTimeMillis());
+			}
+		};
+	}
+
+	private Runnable buildRunnable(final Command command, final SynchronizedStack<String> synchronizedStack, final long sleep) {
+		return new Runnable() {
+			public void run() {
+				try {
+					if (sleep != 0) {
+						Thread.sleep(sleep);
+					}
+					command.execute(synchronizedStack);
+				} catch (Exception ex) {
+					SynchronizedStackTests.this.setExCaught(true);
+				}
+			}
+		};
+	}
+
+	void setExCaught(boolean exCaught) {
+		this.exCaught = exCaught;
+	}
+
+	void setTimeoutOccurred(boolean timeoutOccurred) {
+		this.timeoutOccurred = timeoutOccurred;
+	}
+
+	void setStartTime(long startTime) {
+		this.startTime = startTime;
+	}
+
+	void setEndTime(long endTime) {
+		this.endTime = endTime;
+	}
+
+	void setPoppedObject(Object poppedObject) {
+		this.poppedObject = poppedObject;
+	}
+
+	long elapsedTime() {
+		return this.endTime - this.startTime;
+	}
+
+
+	// ********** Command interface **********
+
+	private interface Command {
+		void execute(SynchronizedStack<String> synchronizedStack) throws Exception;
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java
index 76e6717..2978766 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/iterators/JptUtilityIteratorsTests.java
@@ -48,6 +48,7 @@
 
 	private JptUtilityIteratorsTests() {
 		super();
+		throw new UnsupportedOperationException();
 	}
 
 }
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/AbstractModelTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/AbstractModelTests.java
new file mode 100644
index 0000000..554a76a
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/AbstractModelTests.java
@@ -0,0 +1,1687 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.ChangeSupport;
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.ChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeAdapter;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+import org.eclipse.jpt.utility.tests.internal.TestTools;
+
+import junit.framework.TestCase;
+
+public class AbstractModelTests
+	extends TestCase
+	implements StateChangeListener, PropertyChangeListener, CollectionChangeListener, ListChangeListener, TreeChangeListener
+{
+	private TestModel testModel;
+	private static final String TEST_TO_STRING = "this is a test";
+
+	private StateChangeEvent stateChangeEvent;
+	private boolean stateChangedCalled = false;
+
+	private PropertyChangeEvent propertyChangeEvent;
+	private boolean propertyChangeCalled = false;
+	private static final String PROPERTY_NAME = "propertyName";
+	static final Object OLD_OBJECT_VALUE = new Object();
+	static final Object NEW_OBJECT_VALUE = new Object();
+	static final Integer OLD_INT_VALUE = new Integer(27);
+	static final Integer NEW_INT_VALUE = new Integer(42);
+	static final Boolean OLD_BOOLEAN_VALUE = Boolean.TRUE;
+	static final Boolean NEW_BOOLEAN_VALUE = Boolean.FALSE;
+
+	private CollectionChangeEvent collectionChangeEvent;
+	private boolean itemsAddedCollectionCalled = false;
+	private boolean itemsRemovedCollectionCalled = false;
+	private boolean collectionChangedCalled = false;
+	private boolean collectionClearedCalled = false;
+	private static final String COLLECTION_NAME = "collectionName";
+	static final Object ADDED_OBJECT_VALUE = new Object();
+	static final Object REMOVED_OBJECT_VALUE = new Object();
+	static final int TARGET_INDEX = 7;
+	static final int SOURCE_INDEX = 22;
+
+	private ListChangeEvent listChangeEvent;
+	private boolean itemsAddedListCalled = false;
+	private boolean itemsRemovedListCalled = false;
+	private boolean itemsReplacedListCalled = false;
+	private boolean itemsMovedListCalled = false;
+	private boolean listChangedCalled = false;
+	private boolean listClearedCalled = false;
+	private static final String LIST_NAME = "listName";
+	private static final int ADD_INDEX = 3;
+	private static final int REMOVE_INDEX = 5;
+	private static final int REPLACE_INDEX = 2;
+
+	private TreeChangeEvent treeChangeEvent;
+	private boolean nodeAddedCalled = false;
+	private boolean nodeRemovedCalled = false;
+	private boolean treeChangedCalled = false;
+	private boolean treeClearedCalled = false;
+	private static final String TREE_NAME = "treeName";
+	static final Object[] OBJECT_ARRAY_PATH = {new Object(), new Object(), new String()};
+	static final Object[] EMPTY_PATH = {};
+
+	public AbstractModelTests(String name) {
+		super(name);
+	}
+	
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.testModel = new TestModel();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testFireStateChange() {
+		this.stateChangeEvent = null;
+		this.stateChangedCalled = false;
+		this.testModel.addStateChangeListener(this);
+		this.testModel.testFireStateChange();
+		assertNotNull(this.stateChangeEvent);
+		assertEquals(this.testModel, this.stateChangeEvent.getSource());
+		assertTrue(this.stateChangedCalled);
+	}
+
+	public void testFirePropertyChangeObjectObject() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeObjectObject();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeObjectObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeObjectObject();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeObjectObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangeObject() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeObject();
+		this.verifyPropertyChangeEvent(null, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeObject();
+		this.verifyPropertyChangeEvent(null, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeObject();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangeIntInt() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeIntInt();
+		this.verifyPropertyChangeEvent(OLD_INT_VALUE, NEW_INT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeIntInt();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeIntInt();
+		this.verifyPropertyChangeEvent(OLD_INT_VALUE, NEW_INT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeIntInt();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFirePropertyChangeBooleanBoolean() {
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeBooleanBoolean();
+		this.verifyPropertyChangeEvent(OLD_BOOLEAN_VALUE, NEW_BOOLEAN_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(this);
+		this.testModel.testFirePropertyChangeBooleanBoolean();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeBooleanBoolean();
+		this.verifyPropertyChangeEvent(OLD_BOOLEAN_VALUE, NEW_BOOLEAN_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this);
+		this.testModel.testFirePropertyChangeBooleanBoolean();
+		assertNull(this.propertyChangeEvent);
+		assertFalse(this.propertyChangeCalled);
+	}
+
+	public void testFireItemAddedCollection() {
+		this.collectionChangeEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(this);
+		this.testModel.testFireItemAddedCollection();
+		this.verifyCollectionChangeEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionChangeEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(this);
+		this.testModel.testFireItemAddedCollection();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+
+		this.collectionChangeEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireItemAddedCollection();
+		this.verifyCollectionChangeEvent(ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedCollectionCalled);
+
+		this.collectionChangeEvent = null;
+		this.itemsAddedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireItemAddedCollection();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.itemsAddedCollectionCalled);
+	}
+
+	public void testFireItemRemovedCollection() {
+		this.collectionChangeEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(this);
+		this.testModel.testFireItemRemovedCollection();
+		this.verifyCollectionChangeEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionChangeEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(this);
+		this.testModel.testFireItemRemovedCollection();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+
+		this.collectionChangeEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireItemRemovedCollection();
+		this.verifyCollectionChangeEvent(REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedCollectionCalled);
+
+		this.collectionChangeEvent = null;
+		this.itemsRemovedCollectionCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireItemRemovedCollection();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.itemsRemovedCollectionCalled);
+	}
+
+	public void testFireCollectionCleared() {
+		this.collectionChangeEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addCollectionChangeListener(this);
+		this.testModel.testFireCollectionCleared();
+		this.verifyCollectionChangeEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionChangeEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeCollectionChangeListener(this);
+		this.testModel.testFireCollectionCleared();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.collectionClearedCalled);
+
+		this.collectionChangeEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireCollectionCleared();
+		this.verifyCollectionChangeEvent(null);
+		assertTrue(this.collectionClearedCalled);
+
+		this.collectionChangeEvent = null;
+		this.collectionClearedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireCollectionCleared();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.collectionClearedCalled);
+	}
+
+	public void testFireCollectionChanged() {
+		this.collectionChangeEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.addCollectionChangeListener(this);
+		this.testModel.testFireCollectionChanged();
+		this.verifyCollectionChangeEvent(null);
+		assertTrue(this.collectionChangedCalled);
+
+		this.collectionChangeEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.removeCollectionChangeListener(this);
+		this.testModel.testFireCollectionChanged();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.collectionChangedCalled);
+
+		this.collectionChangeEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireCollectionChanged();
+		this.verifyCollectionChangeEvent(null);
+		assertTrue(this.collectionChangedCalled);
+
+		this.collectionChangeEvent = null;
+		this.collectionChangedCalled = false;
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this);
+		this.testModel.testFireCollectionChanged();
+		assertNull(this.collectionChangeEvent);
+		assertFalse(this.collectionChangedCalled);
+	}
+
+	public void testFireItemAddedList() {
+		this.listChangeEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(this);
+		this.testModel.testFireItemAddedList();
+		this.verifyListChangeEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(this);
+		this.testModel.testFireItemAddedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsAddedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemAddedList();
+		this.verifyListChangeEvent(ADD_INDEX, ADDED_OBJECT_VALUE);
+		assertTrue(this.itemsAddedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsAddedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemAddedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsAddedListCalled);
+	}
+
+	public void testFireItemRemovedList() {
+		this.listChangeEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(this);
+		this.testModel.testFireItemRemovedList();
+		this.verifyListChangeEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(this);
+		this.testModel.testFireItemRemovedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsRemovedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemRemovedList();
+		this.verifyListChangeEvent(REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsRemovedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsRemovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemRemovedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsRemovedListCalled);
+	}
+
+	public void testFireItemReplacedList() {
+		this.listChangeEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(this);
+		this.testModel.testFireItemReplacedList();
+		this.verifyListChangeEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(this);
+		this.testModel.testFireItemReplacedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsReplacedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemReplacedList();
+		this.verifyListChangeEvent(REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		assertTrue(this.itemsReplacedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsReplacedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemReplacedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsReplacedListCalled);
+	}
+
+	public void testFireItemMovedList() {
+		this.listChangeEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(this);
+		this.testModel.testFireItemMovedList();
+		this.verifyListChangeEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(this);
+		this.testModel.testFireItemMovedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsMovedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemMovedList();
+		this.verifyListChangeEvent(TARGET_INDEX, SOURCE_INDEX);
+		assertTrue(this.itemsMovedListCalled);
+
+		this.listChangeEvent = null;
+		this.itemsMovedListCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+		this.testModel.testFireItemMovedList();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.itemsMovedListCalled);
+	}
+
+	public void testFireListCleared() {
+		this.listChangeEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addListChangeListener(this);
+		this.testModel.testFireListCleared();
+		this.verifyListChangeEvent(-1, null);
+		assertTrue(this.listClearedCalled);
+
+		this.listChangeEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeListChangeListener(this);
+		this.testModel.testFireListCleared();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.listClearedCalled);
+
+		this.listChangeEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		this.testModel.testFireListCleared();
+		this.verifyListChangeEvent(-1, null);
+		assertTrue(this.listClearedCalled);
+
+		this.listChangeEvent = null;
+		this.listClearedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+		this.testModel.testFireListCleared();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.listClearedCalled);
+	}
+
+	public void testFireListChanged() {
+		this.listChangeEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.addListChangeListener(this);
+		this.testModel.testFireListChanged();
+		this.verifyListChangeEvent(-1, null);
+		assertTrue(this.listChangedCalled);
+
+		this.listChangeEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.removeListChangeListener(this);
+		this.testModel.testFireListChanged();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.listChangedCalled);
+
+		this.listChangeEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		this.testModel.testFireListChanged();
+		this.verifyListChangeEvent(-1, null);
+		assertTrue(this.listChangedCalled);
+
+		this.listChangeEvent = null;
+		this.listChangedCalled = false;
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+		this.testModel.testFireListChanged();
+		assertNull(this.listChangeEvent);
+		assertFalse(this.listChangedCalled);
+	}
+
+	public void testFireNodeAddedObjectArrayPath() {
+		this.treeChangeEvent = null;
+		this.nodeAddedCalled = false;
+		this.testModel.addTreeChangeListener(this);
+		this.testModel.testFireNodeAddedObjectArrayPath();
+		this.verifyTreeChangeEvent(OBJECT_ARRAY_PATH);
+		assertTrue(this.nodeAddedCalled);
+
+		this.treeChangeEvent = null;
+		this.nodeAddedCalled = false;
+		this.testModel.removeTreeChangeListener(this);
+		this.testModel.testFireNodeAddedObjectArrayPath();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.nodeAddedCalled);
+
+		this.treeChangeEvent = null;
+		this.nodeAddedCalled = false;
+		this.testModel.addTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireNodeAddedObjectArrayPath();
+		this.verifyTreeChangeEvent(OBJECT_ARRAY_PATH);
+		assertTrue(this.nodeAddedCalled);
+
+		this.treeChangeEvent = null;
+		this.nodeAddedCalled = false;
+		this.testModel.removeTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireNodeAddedObjectArrayPath();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.nodeAddedCalled);
+	}
+
+	public void testFireNodeRemovedObjectArrayPath() {
+		this.treeChangeEvent = null;
+		this.nodeRemovedCalled = false;
+		this.testModel.addTreeChangeListener(this);
+		this.testModel.testFireNodeRemovedObjectArrayPath();
+		this.verifyTreeChangeEvent(OBJECT_ARRAY_PATH);
+		assertTrue(this.nodeRemovedCalled);
+
+		this.treeChangeEvent = null;
+		this.nodeRemovedCalled = false;
+		this.testModel.removeTreeChangeListener(this);
+		this.testModel.testFireNodeRemovedObjectArrayPath();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.nodeRemovedCalled);
+
+		this.treeChangeEvent = null;
+		this.nodeRemovedCalled = false;
+		this.testModel.addTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireNodeRemovedObjectArrayPath();
+		this.verifyTreeChangeEvent(OBJECT_ARRAY_PATH);
+		assertTrue(this.nodeRemovedCalled);
+
+		this.treeChangeEvent = null;
+		this.nodeRemovedCalled = false;
+		this.testModel.removeTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireNodeRemovedObjectArrayPath();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.nodeRemovedCalled);
+	}
+
+	public void testFireTreeCleared() {
+		this.treeChangeEvent = null;
+		this.treeClearedCalled = false;
+		this.testModel.addTreeChangeListener(this);
+		this.testModel.testFireTreeCleared();
+		this.verifyTreeChangeEvent(EMPTY_PATH);
+		assertTrue(this.treeClearedCalled);
+
+		this.treeChangeEvent = null;
+		this.treeClearedCalled = false;
+		this.testModel.removeTreeChangeListener(this);
+		this.testModel.testFireTreeCleared();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.treeClearedCalled);
+
+		this.treeChangeEvent = null;
+		this.treeClearedCalled = false;
+		this.testModel.addTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireTreeCleared();
+		this.verifyTreeChangeEvent(EMPTY_PATH);
+		assertTrue(this.treeClearedCalled);
+
+		this.treeChangeEvent = null;
+		this.treeClearedCalled = false;
+		this.testModel.removeTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireTreeCleared();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.treeClearedCalled);
+	}
+
+	public void testFireTreeChangedObjectArrayPath() {
+		this.treeChangeEvent = null;
+		this.treeChangedCalled = false;
+		this.testModel.addTreeChangeListener(this);
+		this.testModel.testFireTreeChangedObjectArrayPath();
+		this.verifyTreeChangeEvent(OBJECT_ARRAY_PATH);
+		assertTrue(this.treeChangedCalled);
+
+		this.treeChangeEvent = null;
+		this.treeChangedCalled = false;
+		this.testModel.removeTreeChangeListener(this);
+		this.testModel.testFireTreeChangedObjectArrayPath();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.treeChangedCalled);
+
+		this.treeChangeEvent = null;
+		this.treeChangedCalled = false;
+		this.testModel.addTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireTreeChangedObjectArrayPath();
+		this.verifyTreeChangeEvent(OBJECT_ARRAY_PATH);
+		assertTrue(this.treeChangedCalled);
+
+		this.treeChangeEvent = null;
+		this.treeChangedCalled = false;
+		this.testModel.removeTreeChangeListener(TREE_NAME, this);
+		this.testModel.testFireTreeChangedObjectArrayPath();
+		assertNull(this.treeChangeEvent);
+		assertFalse(this.treeChangedCalled);
+	}
+
+	public void testHasAnyChangeListeners() {
+		assertFalse(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.addPropertyChangeListener(this);
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.removePropertyChangeListener(this);
+
+		assertFalse(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.addPropertyChangeListener(PROPERTY_NAME, this);
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.removePropertyChangeListener(PROPERTY_NAME, this);
+
+		assertFalse(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.addCollectionChangeListener(this);
+		assertTrue(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.removeCollectionChangeListener(this);
+
+		assertFalse(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.addCollectionChangeListener(COLLECTION_NAME, this);
+		assertTrue(this.testModel.hasAnyCollectionChangeListeners(COLLECTION_NAME));
+		this.testModel.removeCollectionChangeListener(COLLECTION_NAME, this);
+
+		assertFalse(this.testModel.hasAnyListChangeListeners(LIST_NAME));
+		this.testModel.addListChangeListener(this);
+		assertTrue(this.testModel.hasAnyListChangeListeners(LIST_NAME));
+		this.testModel.removeListChangeListener(this);
+
+		assertFalse(this.testModel.hasAnyListChangeListeners(LIST_NAME));
+		this.testModel.addListChangeListener(LIST_NAME, this);
+		assertTrue(this.testModel.hasAnyListChangeListeners(LIST_NAME));
+		this.testModel.removeListChangeListener(LIST_NAME, this);
+
+		assertFalse(this.testModel.hasAnyTreeChangeListeners(TREE_NAME));
+		this.testModel.addTreeChangeListener(this);
+		assertTrue(this.testModel.hasAnyTreeChangeListeners(TREE_NAME));
+		this.testModel.removeTreeChangeListener(this);
+
+		assertFalse(this.testModel.hasAnyTreeChangeListeners(TREE_NAME));
+		this.testModel.addTreeChangeListener(TREE_NAME, this);
+		assertTrue(this.testModel.hasAnyTreeChangeListeners(TREE_NAME));
+		this.testModel.removeTreeChangeListener(TREE_NAME, this);
+	}
+
+	public void testAttributeValueHasChanged() {
+		this.testModel.testAttributeValueHasChanged();
+	}
+
+	public void testClone() {
+		assertFalse(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		this.testModel.addPropertyChangeListener(this);
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+
+		// verify that the clone does not have any listeners
+		TestModel clone = this.testModel.clone();
+		assertFalse(clone.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		clone.addPropertyChangeListener(this);
+		assertTrue(clone.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+		// check original
+		assertTrue(this.testModel.hasAnyPropertyChangeListeners(PROPERTY_NAME));
+
+		// now test events fired by original
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		this.testModel.testFirePropertyChangeObjectObject();
+		this.verifyPropertyChangeEvent(OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+
+		// now test events fired by clone
+		this.propertyChangeEvent = null;
+		this.propertyChangeCalled = false;
+		clone.testFirePropertyChangeObjectObject();
+		this.verifyPropertyChangeEvent(clone, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		assertTrue(this.propertyChangeCalled);
+	}
+
+	public void testAddNullStateListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addStateChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullPropertyListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addPropertyChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullCollectionListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addCollectionChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullListListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addListChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullTreeListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addTreeChangeListener(null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullPropertyListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addPropertyChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullCollectionListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addCollectionChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullListListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addListChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testAddNullTreeListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.addTreeChangeListener("foo", null);
+		} catch (NullPointerException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusStateListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeStateChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeStateChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addStateChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeStateChangeListener(new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusPropertyListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addCollectionChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener(new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusCollectionListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addCollectionChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener(new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusListListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeListChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addListChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener(new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusTreeListener() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeTreeChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeTreeChangeListener(this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addTreeChangeListener(this);
+		exCaught = false;
+		try {
+			this.testModel.removeTreeChangeListener(new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusPropertyListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addCollectionChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removePropertyChangeListener("foo", new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusCollectionListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addCollectionChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removeCollectionChangeListener("foo", new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusListListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addListChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removeListChangeListener("foo", new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testRemoveBogusTreeListenerName() {
+		boolean exCaught = false;
+		try {
+			this.testModel.removeTreeChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addPropertyChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removeTreeChangeListener("foo", this);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+
+		this.testModel.addTreeChangeListener("foo", this);
+		exCaught = false;
+		try {
+			this.testModel.removeTreeChangeListener("foo", new AbstractModelTests("dummy"));
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testToString() {
+		assertTrue(this.testModel.toString().indexOf(TEST_TO_STRING) != -1);
+	}
+
+// ********** internal methods **********
+
+	private void verifyPropertyChangeEvent(Object oldValue, Object newValue) {
+		this.verifyPropertyChangeEvent(this.testModel, oldValue, newValue);
+	}
+
+	private void verifyPropertyChangeEvent(Object source, Object oldValue, Object newValue) {
+		assertNotNull(this.propertyChangeEvent);
+		assertEquals(source, this.propertyChangeEvent.getSource());
+		assertEquals(PROPERTY_NAME, this.propertyChangeEvent.propertyName());
+		assertEquals(oldValue, this.propertyChangeEvent.oldValue());
+		assertEquals(newValue, this.propertyChangeEvent.newValue());
+	}
+
+	private void verifyCollectionChangeEvent(Object item) {
+		assertNotNull(this.collectionChangeEvent);
+		assertEquals(this.testModel, this.collectionChangeEvent.getSource());
+		assertEquals(COLLECTION_NAME, this.collectionChangeEvent.collectionName());
+		if (item == null) {
+			assertFalse(this.collectionChangeEvent.items().hasNext());
+		} else {
+			assertEquals(item, this.collectionChangeEvent.items().next());
+		}
+	}
+
+	private void verifyListChangeEvent(int index, Object item) {
+		this.verifyListChangeEvent(index, item, null);
+	}
+
+	private void verifyListChangeEvent(int targetIndex, int sourceIndex) {
+		assertNotNull(this.listChangeEvent);
+		assertEquals(this.testModel, this.listChangeEvent.getSource());
+		assertEquals(LIST_NAME, this.listChangeEvent.listName());
+		assertEquals(targetIndex, this.listChangeEvent.targetIndex());
+		assertEquals(sourceIndex, this.listChangeEvent.sourceIndex());
+	}
+
+	private void verifyListChangeEvent(int index, Object item, Object replacedItem) {
+		assertNotNull(this.listChangeEvent);
+		assertEquals(this.testModel, this.listChangeEvent.getSource());
+		assertEquals(LIST_NAME, this.listChangeEvent.listName());
+		assertEquals(index, this.listChangeEvent.index());
+		if (item == null) {
+			assertFalse(this.listChangeEvent.items().hasNext());
+		} else {
+			assertEquals(item, this.listChangeEvent.items().next());
+		}
+		if (replacedItem == null) {
+			assertFalse(this.listChangeEvent.replacedItems().hasNext());
+		} else {
+			assertEquals(replacedItem, this.listChangeEvent.replacedItems().next());
+		}
+	}
+
+	private void verifyTreeChangeEvent(Object[] path) {
+		assertNotNull(this.treeChangeEvent);
+		assertEquals(this.testModel, this.treeChangeEvent.getSource());
+		assertEquals(TREE_NAME, this.treeChangeEvent.treeName());
+		assertTrue(Arrays.equals(path, this.treeChangeEvent.path()));
+	}
+
+// ********** listener implementations **********
+
+	public void stateChanged(StateChangeEvent e) {
+		this.stateChangedCalled = true;
+		this.stateChangeEvent = e;
+	}
+
+	public void propertyChanged(PropertyChangeEvent e) {
+		this.propertyChangeCalled = true;
+		this.propertyChangeEvent = e;
+	}
+
+	public void itemsAdded(CollectionChangeEvent e) {
+		this.itemsAddedCollectionCalled = true;
+		this.collectionChangeEvent = e;
+	}
+	public void itemsRemoved(CollectionChangeEvent e) {
+		this.itemsRemovedCollectionCalled = true;
+		this.collectionChangeEvent = e;
+	}
+	public void collectionCleared(CollectionChangeEvent e) {
+		this.collectionClearedCalled = true;
+		this.collectionChangeEvent = e;
+	}
+	public void collectionChanged(CollectionChangeEvent e) {
+		this.collectionChangedCalled = true;
+		this.collectionChangeEvent = e;
+	}
+
+	public void itemsAdded(ListChangeEvent e) {
+		this.itemsAddedListCalled = true;
+		this.listChangeEvent = e;
+	}
+	public void itemsRemoved(ListChangeEvent e) {
+		this.itemsRemovedListCalled = true;
+		this.listChangeEvent = e;
+	}
+	public void itemsReplaced(ListChangeEvent e) {
+		this.itemsReplacedListCalled = true;
+		this.listChangeEvent = e;
+	}
+	public void itemsMoved(ListChangeEvent e) {
+		this.itemsMovedListCalled = true;
+		this.listChangeEvent = e;
+	}
+	public void listCleared(ListChangeEvent e) {
+		this.listClearedCalled = true;
+		this.listChangeEvent = e;
+	}
+	public void listChanged(ListChangeEvent e) {
+		this.listChangedCalled = true;
+		this.listChangeEvent = e;
+	}
+
+	public void nodeAdded(TreeChangeEvent e) {
+		this.nodeAddedCalled = true;
+		this.treeChangeEvent = e;
+	}
+	public void nodeRemoved(TreeChangeEvent e) {
+		this.nodeRemovedCalled = true;
+		this.treeChangeEvent = e;
+	}
+	public void treeCleared(TreeChangeEvent e) {
+		this.treeClearedCalled = true;
+		this.treeChangeEvent = e;
+	}
+	public void treeChanged(TreeChangeEvent e) {
+		this.treeChangedCalled = true;
+		this.treeChangeEvent = e;
+	}
+
+	// ********** inner class **********
+	
+	private static class TestModel extends AbstractModel implements Cloneable {
+		TestModel() {
+			super();
+		}
+	
+		public void testFireStateChange() {
+			this.fireStateChanged();
+		}
+	
+		public void testFirePropertyChangeObjectObject() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_OBJECT_VALUE, NEW_OBJECT_VALUE);
+		}
+	
+		public void testFirePropertyChangeObject() {
+			this.firePropertyChanged(PROPERTY_NAME, NEW_OBJECT_VALUE);
+		}
+	
+		public void testFirePropertyChangeIntInt() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_INT_VALUE.intValue(), NEW_INT_VALUE.intValue());
+		}
+	
+		public void testFirePropertyChangeBooleanBoolean() {
+			this.firePropertyChanged(PROPERTY_NAME, OLD_BOOLEAN_VALUE.booleanValue(), NEW_BOOLEAN_VALUE.booleanValue());
+		}
+	
+		public void testFireItemAddedCollection() {
+			this.fireItemAdded(COLLECTION_NAME, ADDED_OBJECT_VALUE);
+		}
+	
+		public void testFireItemRemovedCollection() {
+			this.fireItemRemoved(COLLECTION_NAME, REMOVED_OBJECT_VALUE);
+		}
+	
+		public void testFireCollectionCleared() {
+			this.fireCollectionCleared(COLLECTION_NAME);
+		}
+	
+		public void testFireCollectionChanged() {
+			this.fireCollectionChanged(COLLECTION_NAME);
+		}
+	
+		public void testFireItemAddedList() {
+			this.fireItemAdded(LIST_NAME, ADD_INDEX, ADDED_OBJECT_VALUE);
+		}
+	
+		public void testFireItemRemovedList() {
+			this.fireItemRemoved(LIST_NAME, REMOVE_INDEX, REMOVED_OBJECT_VALUE);
+		}
+	
+		public void testFireItemReplacedList() {
+			this.fireItemReplaced(LIST_NAME, REPLACE_INDEX, ADDED_OBJECT_VALUE, REMOVED_OBJECT_VALUE);
+		}
+	
+		public void testFireItemMovedList() {
+			this.fireItemMoved(LIST_NAME, TARGET_INDEX, SOURCE_INDEX);
+		}
+	
+		public void testFireListCleared() {
+			this.fireListCleared(LIST_NAME);
+		}
+	
+		public void testFireListChanged() {
+			this.fireListChanged(LIST_NAME);
+		}
+	
+		public void testFireNodeAddedObjectArrayPath() {
+			this.fireNodeAdded(TREE_NAME, OBJECT_ARRAY_PATH);
+		}
+	
+		public void testFireNodeRemovedObjectArrayPath() {
+			this.fireNodeRemoved(TREE_NAME, OBJECT_ARRAY_PATH);
+		}
+	
+		public void testFireTreeCleared() {
+			this.fireTreeCleared(TREE_NAME);
+		}
+	
+		public void testFireTreeChangedObjectArrayPath() {
+			this.fireTreeChanged(TREE_NAME, OBJECT_ARRAY_PATH);
+		}
+	
+		public void testAttributeValueHasChanged() {
+			assertTrue(this.attributeValueHasChanged(null, new Object()));
+			assertTrue(this.attributeValueHasChanged(new Object(), null));
+			assertTrue(this.attributeValueHasChanged(new Object(), new Object()));
+	
+			Object same = new Object();
+			assertFalse(this.attributeValueHasChanged(same, same));
+			assertFalse(this.attributeValueHasChanged(null, null));
+		}
+	
+		@Override
+		public TestModel clone() {
+			try {
+				return (TestModel) super.clone();
+			} catch (CloneNotSupportedException ex) {
+				throw new InternalError();
+			}
+		}
+	
+		@Override
+		public void toString(StringBuffer sb) {
+			sb.append(TEST_TO_STRING);
+		}
+	
+	}
+
+
+	// ********** serialization test **********	
+
+	public void testSerialization() throws IOException, ClassNotFoundException {
+		LocalModel model1 = new LocalModel();
+		Foo foo1 = new Foo();
+		Bar bar1 = new Bar();
+		Joo joo1 = new Joo();
+		Jar jar1 = new Jar();
+		model1.addStateChangeListener(foo1);
+		model1.addStateChangeListener(bar1);
+		model1.addListChangeListener(joo1);
+		model1.addListChangeListener(jar1);
+
+		ChangeListener[] listeners1 = this.listeners(model1, StateChangeListener.class);
+		assertEquals(2, listeners1.length);
+		// the order of these could change...
+		assertEquals(Foo.class, listeners1[0].getClass());
+		assertEquals(Bar.class, listeners1[1].getClass());
+
+		listeners1 = this.listeners(model1, ListChangeListener.class);
+		assertEquals(2, listeners1.length);
+		// the order of these could change...
+		assertEquals(Joo.class, listeners1[0].getClass());
+		assertEquals(Jar.class, listeners1[1].getClass());
+
+		LocalModel model2 = TestTools.serialize(model1);
+
+		ChangeListener[] listeners2 = this.listeners(model2, StateChangeListener.class);
+		assertEquals(1, listeners2.length);
+		assertEquals(Foo.class, listeners2[0].getClass());
+
+		listeners2 = this.listeners(model2, ListChangeListener.class);
+		assertEquals(1, listeners2.length);
+		assertEquals(Joo.class, listeners2[0].getClass());
+	}
+
+	private ChangeListener[] listeners(LocalModel model, Class<? extends ChangeListener> listenerClass) {
+		ChangeSupport changeSupport = (ChangeSupport) ClassTools.getFieldValue(model, "changeSupport");
+		return (ChangeListener[]) ClassTools.executeMethod(changeSupport, "listeners", Class.class, listenerClass);
+	}
+
+	private static class LocalModel extends AbstractModel implements Serializable {
+		LocalModel() {
+			super();
+		}
+	}
+
+	private static class Foo implements Serializable, StateChangeListener {
+		Foo() {
+			super();
+		}
+		public void stateChanged(StateChangeEvent event) {
+			// do nothing
+		}
+	}
+
+	private static class Bar implements StateChangeListener {
+		Bar() {
+			super();
+		}
+		public void stateChanged(StateChangeEvent event) {
+			// do nothing
+		}
+	}
+
+	private static class Joo extends ListChangeAdapter implements Serializable {
+//		private static final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField("changeSupport", ChangeSupport.class)};
+		Joo() {
+			super();
+		}
+	}
+
+	private static class Jar extends ListChangeAdapter {
+		Jar() {
+			super();
+		}
+	}
+
+
+	// ********** bug(?) test **********	
+
+	private static final String ISE_MESSAGE = "this object is no longer listening to localA";
+
+	/**
+	 * Test the following situation:
+	 * 	- both B and C are listening to A
+	 * 	- C is also listening to B
+	 * 	- when B receives an event from A, it will fire an event to C
+	 * 	- when C receives an event from B, it will STOP listening to A
+	 * 	- the event from B to C may be preceded or followed (depending on
+	 * 		the hash positions of listeners) by an event from A to C:
+	 * 		- if the A to C event comes first, no problem
+	 * 		- but if the A to B event comes first, the A to C event should NOT happen
+	 */
+	public void testIndirectRemoveStateListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				public void notifyListeners(LocalA localA) {
+					localA.notifyStateListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemovePropertyListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				public void notifyListeners(LocalA localA) {
+					localA.notifyPropertyListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemoveCollectionListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				public void notifyListeners(LocalA localA) {
+					localA.notifyCollectionListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemoveListListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				public void notifyListeners(LocalA localA) {
+					localA.notifyListListeners();
+				}
+			}
+		);
+	}
+
+	public void testIndirectRemoveTreeListener() {
+		this.verifyIndirectRemoveListener(
+			new NotifyCommand() {
+				public void notifyListeners(LocalA localA) {
+					localA.notifyTreeListeners();
+				}
+			}
+		);
+	}
+
+	public void verifyIndirectRemoveListener(NotifyCommand command) {
+		LocalA localA = new LocalA();
+		LocalB localB = new LocalB(localA);
+
+		// build a bunch of LocalCs so at least one of them is notified AFTER the LocalB;
+		// using 1000 seemed to fail very consistently before ChangeSupport was fixed
+		LocalC[] localCs = new LocalC[1000];
+		for (int i = localCs.length; i-- > 0; ) {
+			localCs[i] = new LocalC(localA, localB);
+		}
+
+		boolean exCaught = false;
+		try {
+			command.notifyListeners(localA);
+		} catch (IllegalStateException ex) {
+			if (ex.getMessage() == ISE_MESSAGE) {
+				exCaught = true;
+			} else {
+				throw ex;
+			}
+		}
+		assertFalse(exCaught);
+
+		for (int i = localCs.length; i-- > 0; ) {
+			assertFalse(localCs[i].isListeningToLocalA());
+		}
+	}
+
+	private interface NotifyCommand {
+		void notifyListeners(LocalA localA);
+	}
+
+	/**
+	 * This object simply fires a state change event. Both LocalB and LocalC
+	 * will be listeners.
+	 */
+	private static class LocalA extends AbstractModel {
+		LocalA() {
+			super();
+		}
+		void notifyStateListeners() {
+			this.fireStateChanged();
+		}
+		void notifyPropertyListeners() {
+			this.firePropertyChanged("foo", 1, 2);
+		}
+		void notifyCollectionListeners() {
+			this.fireCollectionChanged("foo");
+		}
+		void notifyListListeners() {
+			this.fireListChanged("foo");
+		}
+		void notifyTreeListeners() {
+			this.fireTreeChanged("foo");
+		}
+	}
+
+	/**
+	 * This object will fire state change events whenever it receives
+	 * a state change event from localA.
+	 */
+	private static class LocalB
+		extends AbstractModel
+		implements StateChangeListener, PropertyChangeListener, CollectionChangeListener, ListChangeListener, TreeChangeListener
+	{
+		LocalB(LocalA localA) {
+			super();
+			localA.addStateChangeListener(this);
+			localA.addPropertyChangeListener(this);
+			localA.addCollectionChangeListener(this);
+			localA.addListChangeListener(this);
+			localA.addTreeChangeListener(this);
+		}
+
+		public void stateChanged(StateChangeEvent e) {
+			this.fireStateChanged();
+		}
+
+		public void propertyChanged(PropertyChangeEvent evt) {
+			this.firePropertyChanged("bar", 1, 2);
+		}
+
+		public void collectionChanged(CollectionChangeEvent e) {
+			this.fireCollectionChanged("bar");
+		}
+		public void collectionCleared(CollectionChangeEvent e) {/*ignore*/}
+		public void itemsAdded(CollectionChangeEvent e) {/*ignore*/}
+		public void itemsRemoved(CollectionChangeEvent e) {/*ignore*/}
+
+		public void listChanged(ListChangeEvent e) {
+			this.fireListChanged("bar");
+		}
+		public void listCleared(ListChangeEvent e) {/*ignore*/}
+		public void itemsAdded(ListChangeEvent e) {/*ignore*/}
+		public void itemsRemoved(ListChangeEvent e) {/*ignore*/}
+		public void itemsReplaced(ListChangeEvent e) {/*ignore*/}
+		public void itemsMoved(ListChangeEvent e) {/*ignore*/}
+
+		public void treeChanged(TreeChangeEvent e) {
+			this.fireTreeChanged("bar");
+		}
+		public void treeCleared(TreeChangeEvent e) {/*ignore*/}
+		public void nodeAdded(TreeChangeEvent e) {/*ignore*/}
+		public void nodeRemoved(TreeChangeEvent e) {/*ignore*/}
+
+	}
+
+	/**
+	 * This object will listen to two other objects, localA and localB.
+	 * If this object receives notification from localB, it will stop listening to
+	 * localA. If this object receives notification from localA, it will check to
+	 * see whether it still listening to localA. If this object is no longer
+	 * listening to localA, it will complain about receiving the event and
+	 * throw an exception.
+	 */
+	private static class LocalC
+		extends AbstractModel
+		implements StateChangeListener, PropertyChangeListener, CollectionChangeListener, ListChangeListener, TreeChangeListener
+	{
+		private LocalA localA;
+		private LocalB localB;
+		private boolean listeningToLocalA;
+
+		LocalC(LocalA localA, LocalB localB) {
+			super();
+			this.localA = localA;
+			this.localB = localB;
+
+			localA.addStateChangeListener(this);
+			localA.addPropertyChangeListener(this);
+			localA.addCollectionChangeListener(this);
+			localA.addListChangeListener(this);
+			localA.addTreeChangeListener(this);
+			this.listeningToLocalA = true;
+
+			localB.addStateChangeListener(this);
+			localB.addPropertyChangeListener(this);
+			localB.addCollectionChangeListener(this);
+			localB.addListChangeListener(this);
+			localB.addTreeChangeListener(this);
+		}
+		boolean isListeningToLocalA() {
+			return this.listeningToLocalA;
+		}
+
+		public void stateChanged(StateChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeStateChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+
+		public void propertyChanged(PropertyChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removePropertyChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+
+		public void collectionChanged(CollectionChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeCollectionChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+		public void collectionCleared(CollectionChangeEvent e) {/*ignore*/}
+		public void itemsAdded(CollectionChangeEvent e) {/*ignore*/}
+		public void itemsRemoved(CollectionChangeEvent e) {/*ignore*/}
+
+		public void listChanged(ListChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeListChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+		public void listCleared(ListChangeEvent e) {/*ignore*/}
+		public void itemsAdded(ListChangeEvent e) {/*ignore*/}
+		public void itemsRemoved(ListChangeEvent e) {/*ignore*/}
+		public void itemsReplaced(ListChangeEvent e) {/*ignore*/}
+		public void itemsMoved(ListChangeEvent e) {/*ignore*/}
+
+		public void treeChanged(TreeChangeEvent e) {
+			Object source = e.getSource();
+			if (source == this.localA) {
+				if ( ! this.listeningToLocalA) {
+					throw new IllegalStateException(ISE_MESSAGE);
+				}
+			} else if (source == this.localB) {
+				this.localA.removeTreeChangeListener(this);
+				this.listeningToLocalA = false;
+			} else {
+				throw new IllegalStateException("bogus event source: " + source);
+			}
+		}
+		public void treeCleared(TreeChangeEvent e) {/*ignore*/}
+		public void nodeAdded(TreeChangeEvent e) {/*ignore*/}
+		public void nodeRemoved(TreeChangeEvent e) {/*ignore*/}
+
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/JptUtilityModelTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/JptUtilityModelTests.java
new file mode 100644
index 0000000..f01366a
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/JptUtilityModelTests.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.tests.internal.model.listener.JptUtilityModelListenerTests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class JptUtilityModelTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite(ClassTools.packageNameFor(JptUtilityModelTests.class));
+
+		suite.addTest(JptUtilityModelListenerTests.suite());
+		suite.addTestSuite(AbstractModelTests.class);
+
+		return suite;
+	}
+
+	private JptUtilityModelTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/JptUtilityModelListenerTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/JptUtilityModelListenerTests.java
new file mode 100644
index 0000000..1a3b559
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/JptUtilityModelListenerTests.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model.listener;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class JptUtilityModelListenerTests {
+	
+	public static Test suite() {
+		TestSuite suite = new TestSuite(ClassTools.packageNameFor(JptUtilityModelListenerTests.class));
+
+		suite.addTestSuite(ReflectiveCollectionChangeListenerTests.class);
+		suite.addTestSuite(ReflectiveListChangeListenerTests.class);
+		suite.addTestSuite(ReflectivePropertyChangeListenerTests.class);
+		suite.addTestSuite(ReflectiveStateChangeListenerTests.class);
+		suite.addTestSuite(ReflectiveTreeChangeListenerTests.class);
+	
+		return suite;
+	}
+	
+	private JptUtilityModelListenerTests() {
+		super();
+		throw new UnsupportedOperationException();
+	}
+	
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveCollectionChangeListenerTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveCollectionChangeListenerTests.java
new file mode 100644
index 0000000..a60f0b5
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveCollectionChangeListenerTests.java
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model.listener;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.event.CollectionChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ReflectiveChangeListener;
+
+import junit.framework.TestCase;
+
+public class ReflectiveCollectionChangeListenerTests extends TestCase {
+	
+	public ReflectiveCollectionChangeListenerTests(String name) {
+		super(name);
+	}
+
+	private CollectionChangeListener buildZeroArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedZeroArgument", "itemRemovedZeroArgument", "collectionClearedZeroArgument", "collectionChangedZeroArgument");
+	}
+
+	private CollectionChangeListener buildSingleArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedSingleArgument", "itemRemovedSingleArgument", "collectionClearedSingleArgument", "collectionChangedSingleArgument");
+	}
+
+	public void testItemAddedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildZeroArgumentListener(target));
+		testModel.addString(string);
+		assertTrue(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.addString(string);
+		assertTrue(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildSingleArgumentListener(target));
+		testModel.addString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertTrue(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.addString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertTrue(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildZeroArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertTrue(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertTrue(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildSingleArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertTrue(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertTrue(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionClearedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildZeroArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertTrue(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionClearedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertTrue(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionClearedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildSingleArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertTrue(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionClearedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertTrue(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionChangedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildZeroArgumentListener(target));
+		testModel.replaceStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertTrue(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionChangedZeroArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildZeroArgumentListener(target));
+		testModel.replaceStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertTrue(target.collectionChangedZeroArgumentFlag);
+		assertFalse(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionChangedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(this.buildSingleArgumentListener(target));
+		testModel.replaceStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertTrue(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testCollectionChangedSingleArgumentNamedCollection() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		testModel.addCollectionChangeListener(TestModel.STRINGS_COLLECTION, this.buildSingleArgumentListener(target));
+		testModel.replaceStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.collectionClearedZeroArgumentFlag);
+		assertFalse(target.collectionClearedSingleArgumentFlag);
+		assertFalse(target.collectionChangedZeroArgumentFlag);
+		assertTrue(target.collectionChangedSingleArgumentFlag);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		boolean exCaught = false;
+		try {
+			CollectionChangeListener listener = ReflectiveChangeListener.buildCollectionChangeListener(target, "collectionChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		Method method = ClassTools.method(target, "collectionChangedDoubleArgument", new Class[] {CollectionChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			CollectionChangeListener listener = ReflectiveChangeListener.buildCollectionChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_COLLECTION, string);
+		// build a COLLECTION change listener and hack it so we
+		// can add it as a LIST change listener
+		Object listener = ReflectiveChangeListener.buildCollectionChangeListener(target, "itemAddedSingleArgument");
+		testModel.addListChangeListener((ListChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeList();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	private class TestModel extends AbstractModel {
+		private Collection<String> strings = new ArrayList<String>();
+			public static final String STRINGS_COLLECTION = "strings";
+		TestModel() {
+			super();
+		}
+		Iterator<String> strings() {
+			return new CloneIterator<String>(this.strings) {
+				@Override
+				protected void remove(String s) {
+					TestModel.this.removeString(s);
+				}
+			};
+		}
+		void addString(String string) {
+			this.addItemToCollection(string, this.strings, STRINGS_COLLECTION);
+		}
+		void removeString(String string) {
+			this.removeItemFromCollection(string, this.strings, STRINGS_COLLECTION);
+		}
+		void clearStrings() {
+			this.clearCollection(this.strings, STRINGS_COLLECTION);
+		}
+		void replaceStrings(String[] newStrings) {
+			this.strings.clear();
+			CollectionTools.addAll(this.strings, newStrings);
+			this.fireCollectionChanged(STRINGS_COLLECTION);
+		}
+		void changeList() {
+			this.fireListChanged("bogus list");
+		}
+	}
+
+	private class Target {
+		TestModel testModel;
+		String collectionName;
+		String string;
+		boolean itemAddedZeroArgumentFlag = false;
+		boolean itemAddedSingleArgumentFlag = false;
+		boolean itemRemovedZeroArgumentFlag = false;
+		boolean itemRemovedSingleArgumentFlag = false;
+		boolean collectionClearedZeroArgumentFlag = false;
+		boolean collectionClearedSingleArgumentFlag = false;
+		boolean collectionChangedZeroArgumentFlag = false;
+		boolean collectionChangedSingleArgumentFlag = false;
+		Target(TestModel testModel, String collectionName, String string) {
+			super();
+			this.testModel = testModel;
+			this.collectionName = collectionName;
+			this.string = string;
+		}
+		void itemAddedZeroArgument() {
+			this.itemAddedZeroArgumentFlag = true;
+		}
+		void itemAddedSingleArgument(CollectionChangeEvent e) {
+			this.itemAddedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.collectionName());
+			assertEquals(this.string, e.items().next());
+		}
+		void itemRemovedZeroArgument() {
+			this.itemRemovedZeroArgumentFlag = true;
+		}
+		void itemRemovedSingleArgument(CollectionChangeEvent e) {
+			this.itemRemovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.collectionName());
+			assertEquals(this.string, e.items().next());
+		}
+		void collectionClearedZeroArgument() {
+			this.collectionClearedZeroArgumentFlag = true;
+		}
+		void collectionClearedSingleArgument(CollectionChangeEvent e) {
+			this.collectionClearedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.collectionName());
+			assertFalse(e.items().hasNext());
+		}
+		void collectionChangedZeroArgument() {
+			this.collectionChangedZeroArgumentFlag = true;
+		}
+		void collectionChangedSingleArgument(CollectionChangeEvent e) {
+			this.collectionChangedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.collectionName, e.collectionName());
+			assertFalse(e.items().hasNext());
+		}
+		void collectionChangedDoubleArgument(CollectionChangeEvent e, Object o) {
+			fail("bogus event: " + e);
+		}
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveListChangeListenerTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveListChangeListenerTests.java
new file mode 100644
index 0000000..ea8b980
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveListChangeListenerTests.java
@@ -0,0 +1,744 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model.listener;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.event.ListChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ListChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ReflectiveChangeListener;
+
+import junit.framework.TestCase;
+
+public class ReflectiveListChangeListenerTests extends TestCase {
+	
+	public ReflectiveListChangeListenerTests(String name) {
+		super(name);
+	}
+
+	private ListChangeListener buildZeroArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildListChangeListener(target, "itemAddedZeroArgument", "itemRemovedZeroArgument", "itemReplacedZeroArgument", "itemMovedZeroArgument", "listClearedZeroArgument", "listChangedZeroArgument");
+	}
+
+	private ListChangeListener buildSingleArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildListChangeListener(target, "itemAddedSingleArgument", "itemRemovedSingleArgument", "itemReplacedSingleArgument", "itemMovedSingleArgument", "listClearedSingleArgument", "listChangedSingleArgument");
+	}
+
+	public void testItemAddedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(this.buildZeroArgumentListener(target));
+		testModel.addString(string);
+		assertTrue(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.addString(string);
+		assertTrue(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(this.buildSingleArgumentListener(target));
+		testModel.addString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertTrue(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemAddedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.addString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertTrue(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(this.buildZeroArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertTrue(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertTrue(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(this.buildSingleArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertTrue(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemRemovedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.removeString(string);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertTrue(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemReplacedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String oldString = "foo";
+		String newString = "bar";
+		testModel.addString(oldString);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
+		testModel.addListChangeListener(this.buildZeroArgumentListener(target));
+		testModel.replaceString(oldString, newString);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertTrue(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemReplacedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String oldString = "foo";
+		String newString = "bar";
+		testModel.addString(oldString);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.replaceString(oldString, newString);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertTrue(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemReplacedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String oldString = "foo";
+		String newString = "bar";
+		testModel.addString(oldString);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
+		testModel.addListChangeListener(this.buildSingleArgumentListener(target));
+		testModel.replaceString(oldString, newString);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertTrue(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemReplacedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String oldString = "foo";
+		String newString = "bar";
+		testModel.addString(oldString);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, newString, 0, oldString);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.replaceString(oldString, newString);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertTrue(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemMovedZeroArgument() {
+		TestModel testModel = new TestModel();
+		testModel.addString("zero");
+		testModel.addString("one");
+		testModel.addString("two");
+		testModel.addString("three");
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
+		testModel.addListChangeListener(this.buildZeroArgumentListener(target));
+		testModel.moveString(0, 2);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertTrue(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemMovedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		testModel.addString("zero");
+		testModel.addString("one");
+		testModel.addString("two");
+		testModel.addString("three");
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.moveString(0, 2);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertTrue(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemMovedSingleArgument() {
+		TestModel testModel = new TestModel();
+		testModel.addString("zero");
+		testModel.addString("one");
+		testModel.addString("two");
+		testModel.addString("three");
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
+		testModel.addListChangeListener(this.buildSingleArgumentListener(target));
+		testModel.moveString(0, 2);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertTrue(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testItemMovedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		testModel.addString("zero");
+		testModel.addString("one");
+		testModel.addString("two");
+		testModel.addString("three");
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, 0, 2);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.moveString(0, 2);
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertTrue(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListClearedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(this.buildZeroArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertTrue(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListClearedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertTrue(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListClearedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(this.buildSingleArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertTrue(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListClearedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.clearStrings();
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertTrue(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListChangedZeroArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(this.buildZeroArgumentListener(target));
+		testModel.replaceAllStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertTrue(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListChangedZeroArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildZeroArgumentListener(target));
+		testModel.replaceAllStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertTrue(target.listChangedZeroArgumentFlag);
+		assertFalse(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListChangedSingleArgument() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(this.buildSingleArgumentListener(target));
+		testModel.replaceAllStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertTrue(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testListChangedSingleArgumentNamedList() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		testModel.addString(string);
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, null, -1);
+		testModel.addListChangeListener(TestModel.STRINGS_LIST, this.buildSingleArgumentListener(target));
+		testModel.replaceAllStrings(new String[] {"bar", "baz"});
+		assertFalse(target.itemAddedZeroArgumentFlag);
+		assertFalse(target.itemAddedSingleArgumentFlag);
+		assertFalse(target.itemRemovedZeroArgumentFlag);
+		assertFalse(target.itemRemovedSingleArgumentFlag);
+		assertFalse(target.itemReplacedZeroArgumentFlag);
+		assertFalse(target.itemReplacedSingleArgumentFlag);
+		assertFalse(target.itemMovedZeroArgumentFlag);
+		assertFalse(target.itemMovedSingleArgumentFlag);
+		assertFalse(target.listClearedZeroArgumentFlag);
+		assertFalse(target.listClearedSingleArgumentFlag);
+		assertFalse(target.listChangedZeroArgumentFlag);
+		assertTrue(target.listChangedSingleArgumentFlag);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		boolean exCaught = false;
+		try {
+			ListChangeListener listener = ReflectiveChangeListener.buildListChangeListener(target, "listChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		Method method = ClassTools.method(target, "listChangedDoubleArgument", new Class[] {ListChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			ListChangeListener listener = ReflectiveChangeListener.buildListChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel();
+		String string = "foo";
+		Target target = new Target(testModel, TestModel.STRINGS_LIST, string, 0);
+		// build a LIST change listener and hack it so we
+		// can add it as a COLLECTION change listener
+		Object listener = ReflectiveChangeListener.buildListChangeListener(target, "itemAddedSingleArgument");
+		testModel.addCollectionChangeListener((CollectionChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeCollection();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	private class TestModel extends AbstractModel {
+		private List<String> strings = new ArrayList<String>();
+			public static final String STRINGS_LIST = "strings";
+		TestModel() {
+			super();
+		}
+		ListIterator<String> strings() {
+			return new CloneListIterator<String>(this.strings);
+		}
+		void addString(String string) {
+			this.addItemToList(string, this.strings, STRINGS_LIST);
+		}
+		void removeString(String string) {
+			this.removeItemFromList(this.strings.indexOf(string), this.strings, STRINGS_LIST);
+		}
+		void replaceString(String oldString, String newString) {
+			this.setItemInList(this.strings.indexOf(oldString), newString, this.strings, STRINGS_LIST);
+		}
+		void moveString(int targetIndex, int sourceIndex) {
+			this.moveItemInList(targetIndex, sourceIndex, this.strings, STRINGS_LIST);
+		}
+		void clearStrings() {
+			this.clearList(this.strings, STRINGS_LIST);
+		}
+		void replaceAllStrings(String[] newStrings) {
+			this.strings.clear();
+			CollectionTools.addAll(this.strings, newStrings);
+			this.fireListChanged(STRINGS_LIST);
+		}
+		void changeCollection() {
+			this.fireCollectionChanged("bogus collection");
+		}
+	}
+
+	private class Target {
+		TestModel testModel;
+		String listName;
+		String string;
+		int index;
+		String replacedString;
+		int sourceIndex;
+		boolean itemAddedZeroArgumentFlag = false;
+		boolean itemAddedSingleArgumentFlag = false;
+		boolean itemRemovedZeroArgumentFlag = false;
+		boolean itemRemovedSingleArgumentFlag = false;
+		boolean itemReplacedZeroArgumentFlag = false;
+		boolean itemReplacedSingleArgumentFlag = false;
+		boolean itemMovedZeroArgumentFlag = false;
+		boolean itemMovedSingleArgumentFlag = false;
+		boolean listClearedZeroArgumentFlag = false;
+		boolean listClearedSingleArgumentFlag = false;
+		boolean listChangedZeroArgumentFlag = false;
+		boolean listChangedSingleArgumentFlag = false;
+		Target(TestModel testModel, String listName, String string, int index) {
+			super();
+			this.testModel = testModel;
+			this.listName = listName;
+			this.string = string;
+			this.index = index;
+		}
+		Target(TestModel testModel, String listName, String string, int index, String replacedString) {
+			this(testModel, listName, string, index);
+			this.replacedString = replacedString;
+		}
+		Target(TestModel testModel, String listName, int targetIndex, int sourceIndex) {
+			super();
+			this.testModel = testModel;
+			this.listName = listName;
+			this.index = targetIndex;
+			this.sourceIndex = sourceIndex;
+		}
+		void itemAddedZeroArgument() {
+			this.itemAddedZeroArgumentFlag = true;
+		}
+		void itemAddedSingleArgument(ListChangeEvent e) {
+			this.itemAddedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.listName());
+			assertEquals(this.string, e.items().next());
+			assertEquals(this.index, e.index());
+		}
+		void itemRemovedZeroArgument() {
+			this.itemRemovedZeroArgumentFlag = true;
+		}
+		void itemRemovedSingleArgument(ListChangeEvent e) {
+			this.itemRemovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.listName());
+			assertEquals(this.string, e.items().next());
+			assertEquals(this.index, e.index());
+		}
+		void itemReplacedZeroArgument() {
+			this.itemReplacedZeroArgumentFlag = true;
+		}
+		void itemReplacedSingleArgument(ListChangeEvent e) {
+			this.itemReplacedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.listName());
+			assertEquals(this.string, e.items().next());
+			assertEquals(this.replacedString, e.replacedItems().next());
+			assertEquals(this.index, e.index());
+		}
+		void itemMovedZeroArgument() {
+			this.itemMovedZeroArgumentFlag = true;
+		}
+		void itemMovedSingleArgument(ListChangeEvent e) {
+			this.itemMovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.listName());
+			assertEquals(this.index, e.targetIndex());
+			assertEquals(this.sourceIndex, e.sourceIndex());
+		}
+		void listChangedZeroArgument() {
+			this.listChangedZeroArgumentFlag = true;
+		}
+		void listClearedSingleArgument(ListChangeEvent e) {
+			this.listClearedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.listName());
+			assertFalse(e.items().hasNext());
+			assertEquals(this.index, e.index());
+		}
+		void listClearedZeroArgument() {
+			this.listClearedZeroArgumentFlag = true;
+		}
+		void listChangedSingleArgument(ListChangeEvent e) {
+			this.listChangedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.listName, e.listName());
+			assertFalse(e.items().hasNext());
+			assertEquals(this.index, e.index());
+		}
+		void listChangedDoubleArgument(ListChangeEvent e, Object o) {
+			fail("bogus event: " + e);
+		}
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectivePropertyChangeListenerTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectivePropertyChangeListenerTests.java
new file mode 100644
index 0000000..3fe86aa
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectivePropertyChangeListenerTests.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model.listener;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ReflectiveChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+
+import junit.framework.TestCase;
+
+public class ReflectivePropertyChangeListenerTests extends TestCase {
+	
+	public ReflectivePropertyChangeListenerTests(String name) {
+		super(name);
+	}
+
+	public void testZeroArgument() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		testModel.addPropertyChangeListener(ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedZeroArgument"));
+		testModel.setValue(99);
+		assertTrue(target.zeroArgumentFlag);
+		assertFalse(target.singleArgumentFlag);
+	}
+
+	public void testZeroArgumentNamedProperty() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedZeroArgument"));
+		testModel.setValue(99);
+		assertTrue(target.zeroArgumentFlag);
+		assertFalse(target.singleArgumentFlag);
+	}
+
+	public void testSingleArgument() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		testModel.addPropertyChangeListener(ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument"));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	/**
+	 * test method that has more general method parameter type
+	 */
+	public void testSingleArgument2() throws Exception {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		Method method = ClassTools.method(target, "propertyChangedSingleArgument2", new Class[] {Object.class});
+		testModel.addPropertyChangeListener(ReflectiveChangeListener.buildPropertyChangeListener(target, method));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	public void testSingleArgumentNamedProperty() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument"));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	/**
+	 * test method that has more general method parameter type
+	 */
+	public void testSingleArgumentNamedProperty2() throws Exception {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		Method method = ClassTools.method(target, "propertyChangedSingleArgument2", new Class[] {Object.class});
+		testModel.addPropertyChangeListener(TestModel.VALUE_PROPERTY, ReflectiveChangeListener.buildPropertyChangeListener(target, method));
+		testModel.setValue(99);
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		// build a PROPERTY change listener and hack it so we
+		// can add it as a STATE change listener
+		Object listener = ReflectiveChangeListener.buildPropertyChangeListener(target, "propertyChangedSingleArgument");
+		testModel.addStateChangeListener((StateChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.setValue(99);
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		boolean exCaught = false;
+		try {
+			PropertyChangeListener listener = ReflectiveChangeListener.buildPropertyChangeListener(target, "stateChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel(7);
+		Target target = new Target(testModel, TestModel.VALUE_PROPERTY, 7, 99);
+		Method method = ClassTools.method(target, "propertyChangedDoubleArgument", new Class[] {PropertyChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			PropertyChangeListener listener = ReflectiveChangeListener.buildPropertyChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	private class TestModel extends AbstractModel {
+		private int value = 0;
+			public static final String VALUE_PROPERTY = "value";
+		TestModel(int value) {
+			super();
+			this.value = value;
+		}
+		void setValue(int value) {
+			int old = this.value;
+			this.value = value;
+			this.firePropertyChanged(VALUE_PROPERTY, old, value);
+			if (old != value) {
+				this.fireStateChanged();
+			}
+		}
+	}
+
+	private class Target {
+		TestModel testModel;
+		String propertyName;
+		Object oldValue;
+		Object newValue;
+		boolean zeroArgumentFlag = false;
+		boolean singleArgumentFlag = false;
+		Target(TestModel testModel, String propertyName, int oldValue, int newValue) {
+			super();
+			this.testModel = testModel;
+			this.propertyName = propertyName;
+			this.oldValue = new Integer(oldValue);
+			this.newValue = new Integer(newValue);
+		}
+		void propertyChangedZeroArgument() {
+			this.zeroArgumentFlag = true;
+		}
+		void propertyChangedSingleArgument(PropertyChangeEvent e) {
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.propertyName, e.propertyName());
+			assertEquals(this.oldValue, e.oldValue());
+			assertEquals(this.newValue, e.newValue());
+		}
+		void propertyChangedSingleArgument2(Object o) {
+			PropertyChangeEvent e = (PropertyChangeEvent) o;
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.propertyName, e.propertyName());
+			assertEquals(this.oldValue, e.oldValue());
+			assertEquals(this.newValue, e.newValue());
+		}
+		void propertyChangedDoubleArgument(PropertyChangeEvent e, Object o) {
+			fail("bogus event: " + e);
+		}
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveStateChangeListenerTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveStateChangeListenerTests.java
new file mode 100644
index 0000000..5dd8c86
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveStateChangeListenerTests.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model.listener;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.event.StateChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ReflectiveChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.StateChangeListener;
+
+import junit.framework.TestCase;
+
+public class ReflectiveStateChangeListenerTests extends TestCase {
+	
+	public ReflectiveStateChangeListenerTests(String name) {
+		super(name);
+	}
+
+	public void testZeroArgument() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedZeroArgument"));
+		testModel.changeState();
+		assertTrue(target.zeroArgumentFlag);
+		assertFalse(target.singleArgumentFlag);
+	}
+
+	public void testSingleArgument() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedSingleArgument"));
+		testModel.changeState();
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	/**
+	 * test method that has more general method parameter type
+	 */
+	public void testSingleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		Method method = ClassTools.method(target, "stateChangedSingleArgument2", new Class[] {Object.class});
+		testModel.addStateChangeListener(ReflectiveChangeListener.buildStateChangeListener(target, method));
+		testModel.changeState();
+		assertFalse(target.zeroArgumentFlag);
+		assertTrue(target.singleArgumentFlag);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		// build a STATE change listener and hack it so we
+		// can add it as a PROPERTY change listener
+		Object listener = ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedSingleArgument");
+		testModel.addPropertyChangeListener((PropertyChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeProperty();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		boolean exCaught = false;
+		try {
+			StateChangeListener listener = ReflectiveChangeListener.buildStateChangeListener(target, "stateChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel();
+		Target target = new Target(testModel);
+		Method method = ClassTools.method(target, "stateChangedDoubleArgument", new Class[] {StateChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			StateChangeListener listener = ReflectiveChangeListener.buildStateChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+
+	private class TestModel extends AbstractModel {
+		TestModel() {
+			super();
+		}
+		void changeState() {
+			this.fireStateChanged();
+		}
+		void changeProperty() {
+			this.firePropertyChanged("value", 55, 42);
+		}
+	}
+
+	private class Target {
+		TestModel testModel;
+		boolean zeroArgumentFlag = false;
+		boolean singleArgumentFlag = false;
+		Target(TestModel testModel) {
+			super();
+			this.testModel = testModel;
+		}
+		void stateChangedZeroArgument() {
+			this.zeroArgumentFlag = true;
+		}
+		void stateChangedSingleArgument(StateChangeEvent e) {
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+		}
+		void stateChangedSingleArgument2(Object e) {
+			this.singleArgumentFlag = true;
+			assertSame(this.testModel, ((StateChangeEvent) e).getSource());
+		}
+		void stateChangedDoubleArgument(StateChangeEvent e, Object o) {
+			fail("bogus event: " + e);
+		}
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveTreeChangeListenerTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveTreeChangeListenerTests.java
new file mode 100644
index 0000000..3798d25
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/model/listener/ReflectiveTreeChangeListenerTests.java
@@ -0,0 +1,515 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.model.listener;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.model.AbstractModel;
+import org.eclipse.jpt.utility.internal.model.event.TreeChangeEvent;
+import org.eclipse.jpt.utility.internal.model.listener.CollectionChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.ReflectiveChangeListener;
+import org.eclipse.jpt.utility.internal.model.listener.TreeChangeListener;
+
+import junit.framework.TestCase;
+
+public class ReflectiveTreeChangeListenerTests extends TestCase {
+	
+	public ReflectiveTreeChangeListenerTests(String name) {
+		super(name);
+	}
+
+	private TreeChangeListener buildZeroArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildTreeChangeListener(target, "nodeAddedZeroArgument", "nodeRemovedZeroArgument", "treeClearedZeroArgument", "treeChangedZeroArgument");
+	}
+
+	private TreeChangeListener buildSingleArgumentListener(Object target) {
+		return ReflectiveChangeListener.buildTreeChangeListener(target, "nodeAddedSingleArgument", "nodeRemovedSingleArgument", "treeClearedSingleArgument", "treeChangedSingleArgument");
+	}
+
+	public void testNodeAddedZeroArgument() {
+		TestModel testModel = new TestModel("root");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(this.buildZeroArgumentListener(target));
+		testModel.addNode("root", "child");
+		assertTrue(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeAddedZeroArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
+		testModel.addNode("root", "child");
+		assertTrue(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeAddedSingleArgument() {
+		TestModel testModel = new TestModel("root");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(this.buildSingleArgumentListener(target));
+		testModel.addNode("root", "child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertTrue(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeAddedSingleArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
+		testModel.addNode("root", "child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertTrue(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeRemovedZeroArgument() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(this.buildZeroArgumentListener(target));
+		testModel.removeNode("child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertTrue(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeRemovedZeroArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
+		testModel.removeNode("child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertTrue(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeRemovedSingleArgument() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(this.buildSingleArgumentListener(target));
+		testModel.removeNode("child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertTrue(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testNodeRemovedSingleArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
+		testModel.removeNode("child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertTrue(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeClearedZeroArgument() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		testModel.addNode("child", "grandchild");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[0]);
+		testModel.addTreeChangeListener(this.buildZeroArgumentListener(target));
+		testModel.clearTree();
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertTrue(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeClearedZeroArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		testModel.addNode("child", "grandchild");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[0]);
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
+		testModel.clearTree();
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertTrue(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeClearedSingleArgument() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		testModel.addNode("child", "grandchild");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[0]);
+		testModel.addTreeChangeListener(this.buildSingleArgumentListener(target));
+		testModel.clearTree();
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertTrue(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeClearedSingleArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		testModel.addNode("child", "grandchild");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[0]);
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
+		testModel.clearTree();
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertTrue(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeChangedZeroArgument() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "another child"});
+		testModel.addTreeChangeListener(this.buildZeroArgumentListener(target));
+		testModel.replaceNode("child", "another child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertTrue(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeChangedZeroArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "another child"});
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildZeroArgumentListener(target));
+		testModel.replaceNode("child", "another child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertTrue(target.treeChangedZeroArgumentFlag);
+		assertFalse(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeChangedSingleArgument() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "another child"});
+		testModel.addTreeChangeListener(this.buildSingleArgumentListener(target));
+		testModel.replaceNode("child", "another child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertTrue(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testTreeChangedSingleArgumentNamedTree() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "another child"});
+		testModel.addTreeChangeListener(TestModel.STRINGS_TREE, this.buildSingleArgumentListener(target));
+		testModel.replaceNode("child", "another child");
+		assertFalse(target.nodeAddedZeroArgumentFlag);
+		assertFalse(target.nodeAddedSingleArgumentFlag);
+		assertFalse(target.nodeRemovedZeroArgumentFlag);
+		assertFalse(target.nodeRemovedSingleArgumentFlag);
+		assertFalse(target.treeClearedZeroArgumentFlag);
+		assertFalse(target.treeClearedSingleArgumentFlag);
+		assertFalse(target.treeChangedZeroArgumentFlag);
+		assertTrue(target.treeChangedSingleArgumentFlag);
+	}
+
+	public void testBogusDoubleArgument1() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		boolean exCaught = false;
+		try {
+			TreeChangeListener listener = ReflectiveChangeListener.buildTreeChangeListener(target, "collectionChangedDoubleArgument");
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getCause().getClass() == NoSuchMethodException.class) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testBogusDoubleArgument2() throws Exception {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		Method method = ClassTools.method(target, "collectionChangedDoubleArgument", new Class[] {TreeChangeEvent.class, Object.class});
+		boolean exCaught = false;
+		try {
+			TreeChangeListener listener = ReflectiveChangeListener.buildTreeChangeListener(target, method);
+			fail("bogus listener: " + listener);
+		} catch (RuntimeException ex) {
+			if (ex.getMessage().equals(method.toString())) {
+				exCaught = true;
+			}
+		}
+		assertTrue(exCaught);
+	}
+
+	public void testListenerMismatch() {
+		TestModel testModel = new TestModel("root");
+		testModel.addNode("root", "child");
+		Target target = new Target(testModel, TestModel.STRINGS_TREE, new String[]{"root", "child"});
+		// build a TREE change listener and hack it so we
+		// can add it as a COLLECTION change listener
+		Object listener = ReflectiveChangeListener.buildTreeChangeListener(target, "nodeAddedSingleArgument");
+		testModel.addCollectionChangeListener((CollectionChangeListener) listener);
+
+		boolean exCaught = false;
+		try {
+			testModel.changeCollection();
+			fail("listener mismatch: " + listener);
+		} catch (IllegalArgumentException ex) {
+			exCaught = true;
+		}
+		assertTrue(exCaught);
+	}
+
+
+	private class TestModel extends AbstractModel {
+		private final String root;
+		private Map<String, Collection<String>> childrenLists = new HashMap<String, Collection<String>>();
+		private Map<String, String> parents = new HashMap<String, String>();
+			public static final String STRINGS_TREE = "strings";
+		TestModel(String root) {
+			super();
+			if (root == null) {
+				throw new NullPointerException();
+			}
+			this.root = root;
+			this.childrenLists.put(root, new ArrayList<String>());
+			this.parents.put(root, null);
+		}
+		String getRoot() {
+			return this.root;
+		}
+		private String[] path(String node) {
+			String temp = node;
+			List<String> reversePath = new ArrayList<String>();
+			do {
+				reversePath.add(temp);
+				temp = this.parents.get(temp);
+			} while (temp != null);
+			return CollectionTools.reverse(reversePath).toArray(new String[reversePath.size()]);
+		}
+		Iterator<String> strings() {
+			return new CloneIterator<String>(this.childrenLists.keySet()) {
+				@Override
+				protected void remove(String s) {
+					TestModel.this.removeNode(s);
+				}
+			};
+		}
+		void addNode(String parent, String child) {
+			if ((parent == null) || (child == null)) {
+				throw new NullPointerException();
+			}
+
+			Collection<String> children = this.childrenLists.get(parent);
+			if (children == null) {
+				throw new IllegalStateException("cannot add a child to a non-existent parent");
+			}
+
+			if (this.childrenLists.get(child) != null) {
+				throw new IllegalStateException("cannot add a child that is already in the tree");
+			}
+			
+			children.add(child);
+			this.childrenLists.put(child, new ArrayList<String>());
+			this.parents.put(child, parent);
+			this.fireNodeAdded(STRINGS_TREE, this.path(child));
+		}
+		void removeNode(String node) {
+			if (node == null) {
+				throw new NullPointerException();
+			}
+
+			Collection<String> children = this.childrenLists.get(node);
+			if (children == null) {
+				throw new IllegalStateException("node is not in tree");
+			}
+			Object[] path = this.path(node);
+			for (String s : children) {
+				this.removeNode(s);
+			}
+			this.childrenLists.remove(node);
+			this.parents.remove(node);
+			this.fireNodeRemoved(STRINGS_TREE, path);
+		}
+		void replaceNode(String oldNode, String newNode) {
+			if ((oldNode == null) || (newNode == null)) {
+				throw new NullPointerException();
+			}
+
+			Collection<String> children = this.childrenLists.remove(oldNode);
+			if (children == null) {
+				throw new IllegalStateException("old node is not in tree");
+			}
+			this.childrenLists.put(newNode, children);
+			for (String child : children) {
+				this.parents.put(child, newNode);
+			}
+
+			String parent = this.parents.remove(oldNode);
+			this.parents.put(newNode, parent);
+
+			this.fireTreeChanged(STRINGS_TREE, this.path(newNode));
+		}
+		void clearTree() {
+			this.childrenLists.clear();
+			this.childrenLists.put(root, new ArrayList<String>());
+			this.parents.clear();
+			this.parents.put(root, null);
+			this.fireTreeCleared(STRINGS_TREE);
+		}
+		void changeCollection() {
+			this.fireCollectionChanged("bogus collection");
+		}
+	}
+
+	private class Target {
+		TestModel testModel;
+		String treeName;
+		String[] path;
+		boolean nodeAddedZeroArgumentFlag = false;
+		boolean nodeAddedSingleArgumentFlag = false;
+		boolean nodeRemovedZeroArgumentFlag = false;
+		boolean nodeRemovedSingleArgumentFlag = false;
+		boolean treeClearedZeroArgumentFlag = false;
+		boolean treeClearedSingleArgumentFlag = false;
+		boolean treeChangedZeroArgumentFlag = false;
+		boolean treeChangedSingleArgumentFlag = false;
+		Target(TestModel testModel, String treeName, String[] path) {
+			super();
+			this.testModel = testModel;
+			this.treeName = treeName;
+			this.path = path;
+		}
+		void nodeAddedZeroArgument() {
+			this.nodeAddedZeroArgumentFlag = true;
+		}
+		void nodeAddedSingleArgument(TreeChangeEvent e) {
+			this.nodeAddedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.treeName, e.treeName());
+			assertTrue(Arrays.equals(this.path, e.path()));
+		}
+		void nodeRemovedZeroArgument() {
+			this.nodeRemovedZeroArgumentFlag = true;
+		}
+		void nodeRemovedSingleArgument(TreeChangeEvent e) {
+			this.nodeRemovedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.treeName, e.treeName());
+			assertTrue(Arrays.equals(this.path, e.path()));
+		}
+		void treeClearedZeroArgument() {
+			this.treeClearedZeroArgumentFlag = true;
+		}
+		void treeClearedSingleArgument(TreeChangeEvent e) {
+			this.treeClearedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.treeName, e.treeName());
+			assertTrue(Arrays.equals(this.path, e.path()));
+		}
+		void treeChangedZeroArgument() {
+			this.treeChangedZeroArgumentFlag = true;
+		}
+		void treeChangedSingleArgument(TreeChangeEvent e) {
+			this.treeChangedSingleArgumentFlag = true;
+			assertSame(this.testModel, e.getSource());
+			assertEquals(this.treeName, e.treeName());
+			assertTrue(Arrays.equals(this.path, e.path()));
+		}
+		void collectionChangedDoubleArgument(TreeChangeEvent e, Object o) {
+			fail("bogus event: " + e);
+		}
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java
new file mode 100644
index 0000000..5af287f
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/AbstractNodeModelTests.java
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0, which accompanies this distribution
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.
+ * 
+ * Contributors:
+ *     Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.tests.internal.node;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.HashBag;
+import org.eclipse.jpt.utility.internal.Range;
+import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.node.AbstractNodeModel;
+import org.eclipse.jpt.utility.internal.node.Node;
+import org.eclipse.jpt.utility.internal.node.Problem;
+import org.eclipse.jpt.utility.tests.internal.TestTools;
+
+import junit.framework.TestCase;
+
+public class AbstractNodeModelTests extends TestCase {
+	private TestWorkbenchModel root;
+
+	public AbstractNodeModelTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.root = this.buildRoot();
+	}
+
+	private TestWorkbenchModel buildRoot() {
+		TestWorkbenchModel r = new RootTestWorkbenchModel("root");
+			TestWorkbenchModel node1 = r.addTestChildNamed("node 1");
+				TestWorkbenchModel node1_1 = node1.addTestChildNamed("node 1.1");
+					node1_1.addTestChildNamed("node 1.1.1");
+					node1_1.addTestChildNamed("node 1.1.2");
+					node1_1.addTestChildNamed("node 1.1.3");
+				node1.addTestChildNamed("node 1.2");
+			TestWorkbenchModel node2 = r.addTestChildNamed("node 2");
+				node2.addTestChildNamed("node 2.1");
+				node2.addTestChildNamed("node 2.2");
+			r.addTestChildNamed("node 3");
+			r.addTestChildNamed("node 4");
+
+		// mark the entire tree clean
+		r.markEntireBranchClean();
+		return r;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		TestTools.clear(this);
+		super.tearDown();
+	}
+
+	public void testTestWorkbenchModel() {
+		// make sure our test class works OK...
+		assertNull(this.root.testChildNamed(""));
+		assertNotNull(this.root.testChildNamed("node 1"));
+		assertTrue(this.root.testChildNamed("node 1").isClean());
+		assertTrue(this.root.testChildNamed("node 1").isCleanBranch());
+		assertNotNull(this.root.testChildNamed("node 2"));
+		assertTrue(this.root.testChildNamed("node 2").isClean());
+		assertTrue(this.root.testChildNamed("node 2").isCleanBranch());
+		assertNull(this.root.testChildNamed("node 2.1"));
+
+		assertNull(this.root.testDescendantNamed(""));
+		assertNotNull(this.root.testDescendantNamed("node 1"));
+		assertNotNull(this.root.testDescendantNamed("node 2"));
+		assertNotNull(this.root.testDescendantNamed("node 2.1"));
+		assertTrue(this.root.testDescendantNamed("node 2.1").isClean());
+		assertTrue(this.root.testDescendantNamed("node 2.1").isCleanBranch());
+		assertNotNull(this.root.testDescendantNamed("node 1.1.3"));
+		assertTrue(this.root.testDescendantNamed("node 1.1.3").isClean());
+		assertTrue(this.root.testDescendantNamed("node 1.1.3").isCleanBranch());
+	}
+
+	public void testParentAndChildren() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		assertEquals("node 1.1.3", node.getName());
+		assertEquals(0, CollectionTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.parent();
+		assertEquals("node 1.1", node.getName());
+		assertEquals(3, CollectionTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.parent();
+		assertEquals("node 1", node.getName());
+		assertEquals(2, CollectionTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.parent();
+		assertEquals("root", node.getName());
+		assertEquals(4, CollectionTools.size(node.children()));
+
+		node = (TestWorkbenchModel) node.parent();
+		assertNull(node);
+	}
+
+	public void testDirty() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+		assertTrue(node.isDirty());
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		assertTrue(parent.isClean());
+		assertTrue(this.root.isClean());
+	}
+
+	public void testDirtyUnchangedAttribute() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+		assertTrue(node.isDirty());
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		assertTrue(parent.isClean());
+		assertTrue(this.root.isClean());
+
+		this.root.markEntireBranchClean();
+		// set size to same number - should stay clean
+		node.setSize(42);
+		assertTrue(node.isClean());
+		assertTrue(parent.isClean());
+		assertTrue(this.root.isClean());
+	}
+
+	public void testDirtyBranch() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+		assertTrue(node.isDirtyBranch());
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		assertTrue(parent.isDirtyBranch());
+		assertTrue(this.root.isDirtyBranch());
+
+		parent.setSize(77);
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+
+		node.markEntireBranchClean();
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+	}
+
+	public void testDirtyBranchCleanChildDirtyParent() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setSize(42);
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		parent.setSize(77);
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+
+		// now, clean the child, but leave the parent dirty
+		node.markEntireBranchClean();
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+	}
+
+	public void testDirtyBranchCleanChildDirtyChild() {
+		TestWorkbenchModel node1 = this.root.testDescendantNamed("node 1.1.1");
+		node1.setSize(41);
+		TestWorkbenchModel node2 = this.root.testDescendantNamed("node 1.1.2");
+		node2.setSize(42);
+
+		TestWorkbenchModel parent = (TestWorkbenchModel) node1.parent();
+		assertTrue(parent.isClean());
+		assertTrue(parent.isDirtyBranch());
+
+		// now, clean the first child, but leave the second child dirty
+		node1.markEntireBranchClean();
+		assertTrue(parent.isClean());
+		assertTrue(parent.isDirtyBranch());
+	}
+
+	public void testDirtyBranchForced() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+
+		assertTrue(node.isClean());
+		assertTrue(node.isCleanBranch());
+		assertTrue(parent.isClean());
+		assertTrue(parent.isCleanBranch());
+		assertTrue(this.root.isClean());
+		assertTrue(this.root.isCleanBranch());
+
+		this.root.markEntireBranchDirty();
+
+		assertTrue(node.isDirty());
+		assertTrue(node.isDirtyBranch());
+		assertTrue(parent.isDirty());
+		assertTrue(parent.isDirtyBranch());
+		assertTrue(this.root.isDirty());
+		assertTrue(this.root.isDirtyBranch());
+	}
+
+	public void testDirtyTransientAttribute() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		assertTrue(node.isDirty());
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		assertTrue(parent.isClean());
+		assertTrue(parent.isDirtyBranch());
+		assertTrue(this.root.isClean());
+		assertTrue(this.root.isDirtyBranch());
+
+		this.root.markEntireBranchClean();
+
+		this.root.validateBranch();
+
+		assertTrue(this.root.problemsSize() == 0);
+		assertTrue(node.branchProblems().hasNext());
+		assertTrue(parent.problemsSize() == 0);
+		assertTrue(parent.branchProblems().hasNext());
+		assertTrue(node.problemsSize() > 0);
+
+		// since problems are transient, everything should still be clean
+		assertTrue(node.isClean());
+		assertTrue(node.isCleanBranch());
+		assertTrue(parent.isClean());
+		assertTrue(parent.isCleanBranch());
+		assertTrue(this.root.isClean());
+		assertTrue(this.root.isCleanBranch());
+	}
+
+	public void testProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+
+		this.root.validateBranch();
+
+		assertEquals(0, this.root.problemsSize());
+		assertTrue(node.branchProblems().hasNext());
+		assertEquals(0, parent.problemsSize());
+		assertTrue(parent.branchProblems().hasNext());
+		assertEquals(1, node.problemsSize());
+		Problem problem1 = node.problems().next();
+
+		// now create another problem that should remove the old problem
+		node.setName("STILL BOGUS");
+		this.root.validateBranch();
+
+		assertEquals(0, this.root.problemsSize());
+		assertTrue(node.branchProblems().hasNext());
+		assertEquals(0, parent.problemsSize());
+		assertTrue(parent.branchProblems().hasNext());
+		assertEquals(1, node.problemsSize());
+		Problem problem2 = node.problems().next();
+		assertFalse(problem1 == problem2);
+		problem1 = problem2;
+
+		// now create another problem that should replace the old problem
+		node.setName("STILL BOGUS");
+		this.root.validateBranch();
+
+		assertEquals(0, this.root.problemsSize());
+		assertTrue(node.branchProblems().hasNext());
+		assertEquals(0, parent.problemsSize());
+		assertTrue(parent.branchProblems().hasNext());
+		assertEquals(1, node.problemsSize());
+		problem2 = node.problems().next();
+		// the same problem should be there
+		assertTrue(problem1.equals(problem2));
+	}
+
+	public void testBranchProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		parent.setName("BOGUS TOO");
+		this.root.setName("BOGUS TOO TOO");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(3, this.root.branchProblemsSize());
+		assertEquals(1, parent.problemsSize());
+		assertEquals(2, parent.branchProblemsSize());
+		assertEquals(1, node.problemsSize());
+		assertEquals(1, node.branchProblemsSize());
+
+		node.setName("okie-dokie");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(2, this.root.branchProblemsSize());
+		assertEquals(1, parent.problemsSize());
+		assertEquals(1, parent.branchProblemsSize());
+		assertEquals(0, node.problemsSize());
+		assertEquals(0, node.branchProblemsSize());
+	}
+
+	public void testClearAllBranchProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		parent.setName("BOGUS TOO");
+		this.root.setName("BOGUS TOO TOO");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(3, this.root.branchProblemsSize());
+		assertEquals(1, parent.problemsSize());
+		assertEquals(2, parent.branchProblemsSize());
+		assertEquals(1, node.problemsSize());
+		assertEquals(1, node.branchProblemsSize());
+
+		parent.clearAllBranchProblems();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(1, this.root.branchProblemsSize());
+		assertEquals(0, parent.problemsSize());
+		assertEquals(0, parent.branchProblemsSize());
+		assertEquals(0, node.problemsSize());
+		assertEquals(0, CollectionTools.size(node.branchProblems()));
+	}
+
+	public void testRemovedBranchProblems() {
+		TestWorkbenchModel node = this.root.testDescendantNamed("node 1.1.3");
+		node.setName("BOGUS");
+		TestWorkbenchModel parent = (TestWorkbenchModel) node.parent();
+		parent.setName("BOGUS TOO");
+		this.root.setName("BOGUS TOO TOO");
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(3, CollectionTools.size(this.root.branchProblems()));
+		assertEquals(1, parent.problemsSize());
+		assertEquals(2, parent.branchProblemsSize());
+		assertEquals(1, node.problemsSize());
+		assertEquals(1, CollectionTools.size(node.branchProblems()));
+
+		// completely remove a node that has problems -
+		// the entire tree should recalculate its "branch" problems
+		parent.removeTestChild(node);
+
+		this.root.validateBranch();
+
+		assertEquals(1, this.root.problemsSize());
+		assertEquals(2, CollectionTools.size(this.root.branchProblems()));
+		assertEquals(1, parent.problemsSize());
+		assertEquals(1, parent.branchProblemsSize());
+	}
+
+	public void testSort() {
+		List<TestWorkbenchModel> nodes = this.buildSortedNodes();
+		assertTrue(new Range(0, 1).includes(this.indexOf(nodes, "aaa")));
+		assertTrue(new Range(0, 1).includes(this.indexOf(nodes, "AAA")));
+		assertTrue(new Range(2, 3).includes(this.indexOf(nodes, "bbb")));
+		assertTrue(new Range(2, 3).includes(this.indexOf(nodes, "BBB")));
+		assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "ccc")));
+		assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "CCC")));
+		assertTrue(new Range(4, 6).includes(this.indexOf(nodes, "���")));
+	}
+
+	private int indexOf(List<TestWorkbenchModel> nodes, String nodeName) {
+		for (int i = nodes.size(); i-- > 0; ) {
+			if (nodes.get(i).getName().equals(nodeName)) {
+				return i;
+			}
+		}
+		throw new IllegalArgumentException();
+	}
+
+	private List<TestWorkbenchModel> buildSortedNodes() {
+		List<TestWorkbenchModel> result = new ArrayList<TestWorkbenchModel>();
+		result.add(new RootTestWorkbenchModel("AAA"));
+		result.add(new RootTestWorkbenchModel("BBB"));
+		result.add(new RootTestWorkbenchModel("CCC"));
+		result.add(new RootTestWorkbenchModel("���"));
+		result.add(new RootTestWorkbenchModel("ccc"));
+		result.add(new RootTestWorkbenchModel("bbb"));
+		result.add(new RootTestWorkbenchModel("aaa"));
+		return CollectionTools.sort(result);
+	}
+
+
+	// ********** inner classes **********
+
+	private class TestWorkbenchModel extends AbstractNodeModel {
+		private String name;
+			public static final String NAME_PROPERTY = "name";
+		private int size;
+			public static final String SIZE_PROPERTY = "size";
+		private Collection<TestWorkbenchModel> testChildren;
+			public static final String TEST_CHILDREN_COLLECTION = "children";
+	
+		// ********** construction/initialization **********
+		public TestWorkbenchModel(TestWorkbenchModel parent, String name) {
+			super(parent);
+			if (name == null) {
+				throw new NullPointerException();
+			}
+			this.name = name;
+		}
+		@Override
+		protected void initialize() {
+			super.initialize();
+			this.size = 0;
+			this.testChildren = new HashBag<TestWorkbenchModel>();
+		}
+		
+		@Override
+		protected void checkParent(Node parent) {
+			// do nothing
+		}
+	
+	
+		// ********** accessors **********
+		public String getName() {
+			return this.name;
+		}
+		public void setName(String name) {
+			Object old = this.name;
+			this.name = name;
+			this.firePropertyChanged(NAME_PROPERTY, old, name);
+		}
+	
+		public int getSize() {
+			return this.size;
+		}
+		public void setSize(int size) {
+			int old = this.size;
+			this.size = size;
+			this.firePropertyChanged(SIZE_PROPERTY, old, size);
+		}
+	
+		public Iterator<TestWorkbenchModel> testChildren() {
+			return new CloneIterator<TestWorkbenchModel>(this.testChildren) {
+				@Override
+				protected void remove(TestWorkbenchModel current) {
+					TestWorkbenchModel.this.removeTestChild(current);
+				}
+			};
+		}
+		public int testChildrenSize() {
+			return this.testChildren.size();
+		}
+		private TestWorkbenchModel addTestChild(TestWorkbenchModel testChild) {
+			this.addItemToCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
+			return testChild;
+		}
+		public TestWorkbenchModel addTestChildNamed(String childName) {
+			if (this.testChildNamed(childName) != null) {
+				throw new IllegalArgumentException(childName);
+			}
+			return this.addTestChild(new TestWorkbenchModel(this, childName));
+		}
+		public void removeTestChild(TestWorkbenchModel testChild) {
+			this.removeItemFromCollection(testChild, this.testChildren, TEST_CHILDREN_COLLECTION);
+		}
+	
+		// ********** queries **********
+		public String displayString() {
+			return this.name;
+		}
+		public TestWorkbenchModel testChildNamed(String childName) {
+			for (TestWorkbenchModel testChild : this.testChildren) {
+				if (testChild.getName().equals(childName)) {
+					return testChild;
+				}
+			}
+			return null;
+		}
+		public TestWorkbenchModel testDescendantNamed(String descendantName) {
+			for (TestWorkbenchModel testDescendant : this.testChildren) {
+				if (testDescendant.getName().equals(descendantName)) {
+					return testDescendant;
+				}
+				// recurse...
+				testDescendant = testDescendant.testDescendantNamed(descendantName);
+				if (testDescendant != null) {
+					return testDescendant;
+				}
+			}
+			return null;
+		}
+	
+		// ********** behavior **********
+		@Override
+		protected void addChildrenTo(List<Node> children) {
+			super.addChildrenTo(children);
+			children.addAll(this.testChildren);
+		}
+		@Override
+		protected void addProblemsTo(List<Problem> currentProblems) {
+			super.addProblemsTo(currentProblems);
+			// names must be all lowercase...
+			for (int i = this.name.length(); i-- > 0; ) {
+				char c = this.name.charAt(i);
+				if (Character.isLetter(c) && ! Character.isLowerCase(c)) {
+					currentProblems.add(this.buildProblem("NAME_MUST_BE_LOWERCASE", this.name));
+					return;
+				}
+			}
+		}
+		@Override
+		public void toString(StringBuffer sb) {
+			sb.append(this.name);
+		}
+	}
+
+
+	private class RootTestWorkbenchModel extends TestWorkbenchModel {
+		public RootTestWorkbenchModel(String name) {
+			super(null, name);
+		}
+		@Override
+		public Validator validator() {
+			return Node.NULL_VALIDATOR;
+		}
+	}
+
+}
+
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JptCoreContentJavaMappingsTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java
similarity index 64%
rename from jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JptCoreContentJavaMappingsTests.java
rename to jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java
index ddbb6bd..e16c3ba 100644
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/content/java/mappings/JptCoreContentJavaMappingsTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/node/JptUtilityNodeTests.java
@@ -7,22 +7,25 @@
  * Contributors:
  *     Oracle - initial API and implementation
  ******************************************************************************/
-package org.eclipse.jpt.core.tests.internal.content.java.mappings;
+package org.eclipse.jpt.utility.tests.internal.node;
+
+import org.eclipse.jpt.utility.internal.ClassTools;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
-public class JptCoreContentJavaMappingsTests {
-
+public class JptUtilityNodeTests {
+	
 	public static Test suite() {
-		TestSuite suite = new TestSuite(JptCoreContentJavaMappingsTests.class.getName());
-//		suite.addTestSuite(JavaEntityTests.class);
+		TestSuite suite = new TestSuite(ClassTools.packageNameFor(JptUtilityNodeTests.class));
+	
+		suite.addTestSuite(AbstractNodeModelTests.class);
+	
 		return suite;
 	}
-
-	private JptCoreContentJavaMappingsTests() {
+	
+	private JptUtilityNodeTests() {
 		super();
-		throw new UnsupportedOperationException();
 	}
-
+	
 }